SHARE
TWEET

Ucztujący filozofowie 0.912

PanaPatryk44 Jun 19th, 2017 52 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/bash
  2. # -*- coding: utf-8 -*-
  3.  
  4.  
  5. quiet_run() {
  6.   "$@" >/dev/null 2>&1
  7. }
  8.  
  9. c_locale_run() {
  10.   LC_ALL="C.UTF-8" LANG="C.UTF-8" LANGUAGE="C" "$@"
  11. }
  12.  
  13.  
  14. is_int() {
  15.   c_locale_run quiet_run printf "%d" "$1"
  16. }
  17.  
  18.  
  19. is_float() {
  20.   c_locale_run quiet_run printf "%f" "$1"
  21. }
  22.  
  23. log() {
  24.   DATE_MAIN=`date +"%F %T.%N"`
  25.   echo "[""$DATE_MAIN"" ""$LOG_IDENTITY""PID-""$BASHPID""] " "$@"
  26. }
  27.  
  28. run_philosopher() {
  29.  PHILOSOPHER_ID=$1
  30. TABLE_PATH=$2
  31. MAX_MEALS=$3
  32. EATING_TIME=$4
  33. SLEEPING_TIME=$5
  34.  
  35.  
  36. MESSAGE=""
  37.   MESSAGE="$MESSAGE""Script file: "`realpath -- "$0"`"; "
  38.  
  39.   if [[ "$PHILOSOPHER_ID" -eq "0" ]]
  40.   then
  41.     LOG_IDENTITY="Main"
  42.     MESSAGE="$MESSAGE""Context: ""$LOG_IDENTITY""; "
  43.   else
  44.     MESSAGE="$MESSAGE""Context: ""$LOG_IDENTITY""; "
  45.     if [[ "$PHILOSOPHER_ID" -eq "$PHILOSOPHERS_COUNT" ]]
  46.     then
  47.       FORK_B="$PHILOSOPHER_ID"
  48.       FORK_A="1"
  49.     else
  50.       FORK_A="$PHILOSOPHER_ID"
  51.       FORK_B=$[PHILOSOPHER_ID+1]
  52.     fi
  53.     FORK_A_PATH=`realpath -- "$TABLE_PATH""/""$FORK_A"`
  54.     FORK_B_PATH=`realpath -- "$TABLE_PATH""/""$FORK_B"`
  55.   fi
  56.  
  57.   MESSAGE="$MESSAGE""Table path: \`\`""$TABLE_PATH""''; "
  58.   if [[ "$PHILOSOPHER_ID" -ne "0" ]]
  59.   then
  60.     MESSAGE="$MESSAGE""Primary fork: ""$FORK_A_PATH""; "
  61.     MESSAGE="$MESSAGE""Secondary fork: ""$FORK_B_PATH""; "
  62.   fi
  63.   MESSAGE="$MESSAGE""Philosophers count: ""$PHILOSOPHERS_COUNT""; "
  64.   MESSAGE="$MESSAGE""Maximum meals: ""$MAX_MEALS""; "
  65.  
  66.   if [[ -z $EATING_TIME ]]
  67.   then
  68.     MESSAGE="$MESSAGE""Eating time: randomized; "
  69.   else
  70.     MESSAGE="$MESSAGE""Eating time: ""$EATING_TIME""s; "
  71.   fi
  72.  
  73.   if [[ -z $SLEEPING_TIME ]]
  74.   then
  75.     MESSAGE="$MESSAGE""Sleeping time: randomized; "
  76.   else
  77.     MESSAGE="$MESSAGE""Sleeping time: ""$SLEEPING_TIME""s; "
  78.   fi
  79.  
  80.   log "FID#$PHILOSOPHER_ID ""^^^START^^^ ""$MESSAGE"
  81.  
  82.   HALF_TIME=$[(MAX_MEALS+1)/2]
  83.   MEALS_CONSUMED=0
  84.  
  85.   for MEAL_ID in `seq 1 "$MAX_MEALS"`
  86.   do
  87.     ACTUAL_EATING_TIME=${EATING_TIME:-`random_time`}
  88.     ACTUAL_SLEEPING_TIME=${SLEEPING_TIME:-`random_time`}
  89.    
  90.     log "FID#$PHILOSOPHER_ID ""FID#$PHILOSOPHER_ID ""Trying to acquire Fork WID#""$FORK_A"
  91.     (
  92.       flock -x 9
  93.        log "FID#$PHILOSOPHER_ID ""Fork WID#""$FORK_A"" acquired successfully(exclusive lock put on fork "$FORK_A")"
  94.      
  95.       log "FID#$PHILOSOPHER_ID ""Trying to acquire Fork WID#""$FORK_B(trying to put exclusive lock on fork "$FORK_B")"
  96.       (
  97.         flock -x 10
  98.         log "FID#$PHILOSOPHER_ID ""Fork WID#""$FORK_B"" acquired successfully(exclusive lock put on fork "$FORK_B")"
  99.        
  100.          log "FID#$PHILOSOPHER_ID ""Eating Meal#""$MEAL_ID "" started, it will take ""$ACTUAL_EATING_TIME""s"
  101.          sleep "$ACTUAL_EATING_TIME"
  102.          log "FID#$PHILOSOPHER_ID ""Eating Meal#""$MEAL_ID "" finished"
  103.       ) 10>"$FORK_B_PATH"
  104.       log "FID#$PHILOSOPHER_ID ""Putting Fork WID#""$FORK_A"" back(exclusive lock droped from fork "$FORK_B")"
  105.      
  106.     ) 9>"$FORK_A_PATH"
  107.     log "FID#$PHILOSOPHER_ID ""Putting Fork WID#""$FORK_B"" back(exclusive lock droped from fork "$FORK_B")"
  108.    
  109.     MEALS_CONSUMED=$[MEALS_CONSUMED+1]
  110.    
  111.       log "FID#$PHILOSOPHER_ID ""Sleeping after Meal#""$MEAL_ID "" started, it will take ""$ACTUAL_SLEEPING_TIME""s"
  112.       sleep "$ACTUAL_SLEEPING_TIME"
  113.       log "FID#$PHILOSOPHER_ID ""Sleeping after Meal#""$MEAL_ID "" finished"
  114.    
  115.     if [[ "$MEAL_ID" -eq "$HALF_TIME" ]]
  116.     then
  117.       log "FID#$PHILOSOPHER_ID ""---POŁOWA--- Meals consumed: ""$MEALS_CONSUMED"
  118.       echo > "$TABLE_LOCK"
  119.       read line < "$TABLE_LOCK""1"
  120.       log "FID#$PHILOSOPHER_ID ""Barrier is passed."
  121.      
  122.     fi
  123.   done
  124.  
  125.   log "FID#$PHILOSOPHER_ID ""___STOP___ Meals consumed: ""$MEALS_CONSUMED"
  126. }
  127.  
  128.  
  129.  
  130. random_time() {
  131.   echo "0.""$RANDOM"
  132. }
  133.  
  134.  
  135.  
  136.  
  137. #Scrypt start
  138. while getopts ":s:f:n:k:r:i:" OPT
  139.   do
  140.     case "$OPT" in
  141.       s)
  142.           FAIL=false
  143.           mkdir -p -- "$OPTARG" || FAIL=true
  144.          
  145.           if "$FAIL"
  146.           then
  147.             log "Cannot parse \`\`""$OPTARG""'' as table path."
  148.             exit 1
  149.           else
  150.             TABLE_PATH="$OPTARG"
  151.           fi
  152.         ;;
  153.       f)
  154.           FAIL=false
  155.           is_int "$OPTARG" || FAIL=true
  156.           [[ "$OPTARG" -ge "2" ]] || FAIL=true
  157.          
  158.           if "$FAIL"
  159.           then
  160.             log "Cannot parse \`\`""$OPTARG""'' as number of philosopers."
  161.             exit 1
  162.           else
  163.             PHILOSOPHERS_COUNT="$OPTARG"
  164.           fi
  165.         ;;
  166.       n)
  167.           FAIL=false
  168.           is_int "$OPTARG" || FAIL=true
  169.           [[ "$OPTARG" -ge "0" ]] || FAIL=true
  170.          
  171.           if "$FAIL"
  172.           then
  173.             log "Cannot parse \`\`""$OPTARG""'' as maximum number meals."
  174.             exit 1
  175.           else
  176.             MAX_MEALS="$OPTARG"
  177.           fi
  178.         ;;
  179.       k)
  180.           FAIL=false
  181.           is_float "$OPTARG" || FAIL=true
  182.  
  183.           if (( $(echo "$OPTARG<0" | bc) )); then
  184.           FAIL=true
  185.           fi
  186.  
  187.           if "$FAIL"
  188.           then
  189.             log "Cannot parse \`\`""$OPTARG""'' as eating time."
  190.             exit 1
  191.           else
  192.             EATING_TIME="$OPTARG"
  193.           fi
  194.         ;;
  195.       r)
  196.           FAIL=false
  197.           is_float "$OPTARG" || FAIL=true
  198.           if (( $(echo "$OPTARG<0" | bc) )); then
  199.           FAIL=true
  200.           fi
  201.           if "$FAIL"
  202.           then
  203.             log "Cannot parse \`\`""$OPTARG""'' as sleeping time."
  204.             exit 1
  205.           else
  206.             SLEEPING_TIME="$OPTARG"
  207.           fi
  208.         ;;
  209.       i)
  210.           FAIL=false
  211.           is_int "$OPTARG" || FAIL=true
  212.           [[ "$OPTARG" -ge "1" ]] || FAIL=true
  213.          
  214.           if "$FAIL"
  215.           then
  216.             log "Cannot parse \`\`""$OPTARG""'' as philosopher ID."
  217.             exit 1
  218.           else
  219.             PHILOSOPHER_ID="$OPTARG"
  220.             LOG_IDENTITY="FID#""$PHILOSOPHER_ID"
  221.           fi
  222.         ;;
  223.       \:)
  224.           log "\`\`""-$OPTARG""'' requires some value."
  225.           exit 1
  226.         ;;
  227.       \?)
  228.           log "\`\`""-$OPTARG""'' is not a valid argument."
  229.           exit 1
  230.         ;;
  231.     esac
  232.   done
  233.  
  234.   #EXISTING TABLE ISN'T GUAREANTED TO BE CORRECT. FOR INSTANCE, SOME FORKS COULD BE STILL LOKED BY OTHER PHILOSOPHERS
  235.   TABLE_PATH=${TABLE_PATH:-`mktemp -d -p . --suffix="-stol"`}
  236.   TABLE_PATH=`realpath -- "$TABLE_PATH"`
  237.   PHILOSOPHERS_COUNT=${PHILOSOPHERS_COUNT:-5}
  238.   MAX_MEALS=${MAX_MEALS:-7}
  239.   PHILOSOPHER_ID=${PHILOSOPHER_ID:-0}
  240.   TABLE_LOCK="$TABLE_PATH""/table.lock"
  241.  
  242.   if [[ "$PHILOSOPHER_ID" -gt "$PHILOSOPHERS_COUNT" ]]
  243.   then
  244.     log "Philosopher ID greater than number of philosophers (\`\`""$PHILOSOPHER_ID""'' vs \`\`""$PHILOSOPHERS_COUNT""'')."
  245.     exit 1
  246.   fi
  247.  
  248. mkfifo "$TABLE_LOCK"
  249.     if [ $? -ne 0 ]; then
  250.         log "Failed to create pipe, exiting program with exit code 3..."
  251.         exit 3;
  252.     fi
  253. mkfifo "$TABLE_LOCK""1"
  254.     if [ $? -ne 0 ]; then
  255.         log "Failed to create pipe, exiting program with exit code 3..."
  256.         exit 3;
  257.     fi
  258. a=( $(shuf -e $(seq 1 "$PHILOSOPHERS_COUNT")) )
  259. for i in "${a[@]}"
  260. do
  261.  
  262.    log `hostname`" STARTUJE FILOZOF...  "$i" "$TABLE_PATH" "$MAX_MEALS" "$EATING_TIME" "$SLEEPING_TIME""
  263.    run_philosopher "$i" "$TABLE_PATH" "$MAX_MEALS" "$EATING_TIME" "$SLEEPING_TIME" &
  264. done
  265. for i in `seq 1 "$PHILOSOPHERS_COUNT"`
  266. do
  267.  read line < "$TABLE_LOCK"
  268. done
  269. for i in `seq 1 "$PHILOSOPHERS_COUNT"`
  270. do
  271.  echo > "$TABLE_LOCK""1"
  272. done
  273.  
  274. for CPID in `pgrep -P "$$" | xargs`
  275. do
  276.   wait "$CPID"
  277. done
  278.  
  279. log "___STOP___"
RAW Paste Data
Pastebin PRO Summer Special!
Get 40% OFF on Pastebin PRO accounts!
Top