Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/bash
- # -*- coding: utf-8 -*-
- quiet_run() {
- "$@" >/dev/null 2>&1
- }
- c_locale_run() {
- LC_ALL="C.UTF-8" LANG="C.UTF-8" LANGUAGE="C" "$@"
- }
- is_int() {
- c_locale_run quiet_run printf "%d" "$1"
- }
- is_float() {
- c_locale_run quiet_run printf "%f" "$1"
- }
- log() {
- DATE_MAIN=`date +"%F %T.%N"`
- echo "[""$DATE_MAIN"" ""$LOG_IDENTITY""PID-""$BASHPID""] " "$@"
- }
- run_philosopher() {
- local PHILOSOPHER_ID=$1
- local TABLE_PATH=$2
- local MAX_MEALS=$3
- local EATING_TIME=$4
- local SLEEPING_TIME=$5
- MESSAGE=""
- MESSAGE="$MESSAGE""Script file: "`realpath -- "$0"`"; "
- if [[ "$PHILOSOPHER_ID" -eq "0" ]]
- then
- LOG_IDENTITY="Main"
- MESSAGE="$MESSAGE""Context: ""$LOG_IDENTITY""; "
- else
- MESSAGE="$MESSAGE""Context: ""$LOG_IDENTITY""; "
- if [[ "$PHILOSOPHER_ID" -eq "$PHILOSOPHERS_COUNT" ]]
- then
- FORK_B="$PHILOSOPHER_ID"
- FORK_A="1"
- else
- FORK_A="$PHILOSOPHER_ID"
- FORK_B=$[PHILOSOPHER_ID+1]
- fi
- FORK_A_PATH=`realpath -- "$TABLE_PATH""/""$FORK_A"`
- FORK_B_PATH=`realpath -- "$TABLE_PATH""/""$FORK_B"`
- fi
- MESSAGE="$MESSAGE""Table path: \`\`""$TABLE_PATH""''; "
- if [[ "$PHILOSOPHER_ID" -ne "0" ]]
- then
- MESSAGE="$MESSAGE""Primary fork: ""$FORK_A_PATH""; "
- MESSAGE="$MESSAGE""Secondary fork: ""$FORK_B_PATH""; "
- fi
- MESSAGE="$MESSAGE""Philosophers count: ""$PHILOSOPHERS_COUNT""; "
- MESSAGE="$MESSAGE""Maximum meals: ""$MAX_MEALS""; "
- if [[ -z $EATING_TIME ]]
- then
- MESSAGE="$MESSAGE""Eating time: randomized; "
- else
- MESSAGE="$MESSAGE""Eating time: ""$EATING_TIME""s; "
- fi
- if [[ -z $SLEEPING_TIME ]]
- then
- MESSAGE="$MESSAGE""Sleeping time: randomized; "
- else
- MESSAGE="$MESSAGE""Sleeping time: ""$SLEEPING_TIME""s; "
- fi
- log "FID#$PHILOSOPHER_ID ""^^^START^^^ ""$MESSAGE"
- HALF_TIME=$[(MAX_MEALS+1)/2]
- MEALS_CONSUMED=0
- for MEAL_ID in `seq 1 "$MAX_MEALS"`
- do
- ACTUAL_EATING_TIME=${EATING_TIME:-`random_time`}
- ACTUAL_SLEEPING_TIME=${SLEEPING_TIME:-`random_time`}
- log "FID#$PHILOSOPHER_ID ""FID#$PHILOSOPHER_ID ""Trying to acquire Fork WID#""$FORK_A"
- (
- flock -x 9
- log "FID#$PHILOSOPHER_ID ""Fork WID#""$FORK_A"" acquired successfully (exclusive lock put on fork "$FORK_A")"
- log "FID#$PHILOSOPHER_ID ""Trying to acquire Fork WID#""$FORK_B (trying to put exclusive lock on fork "$FORK_B")"
- (
- flock -x 10
- log "FID#$PHILOSOPHER_ID ""Fork WID#""$FORK_B"" acquired successfully (exclusive lock put on fork "$FORK_B")"
- log "FID#$PHILOSOPHER_ID ""Eating Meal#""$MEAL_ID "" started, it will take ""$ACTUAL_EATING_TIME""s"
- sleep "$ACTUAL_EATING_TIME"
- log "FID#$PHILOSOPHER_ID ""Eating Meal#""$MEAL_ID "" finished"
- ) 10>"$FORK_B_PATH"
- log "FID#$PHILOSOPHER_ID ""Putting Fork WID#""$FORK_A"" back (exclusive lock dropped from fork "$FORK_B")"
- ) 9>"$FORK_A_PATH"
- log "FID#$PHILOSOPHER_ID ""Putting Fork WID#""$FORK_B"" back (exclusive lock dropped from fork "$FORK_B")"
- MEALS_CONSUMED=$[MEALS_CONSUMED+1]
- log "FID#$PHILOSOPHER_ID ""Sleeping after Meal#""$MEAL_ID "" started, it will take ""$ACTUAL_SLEEPING_TIME""s"
- sleep "$ACTUAL_SLEEPING_TIME"
- log "FID#$PHILOSOPHER_ID ""Sleeping after Meal#""$MEAL_ID "" finished"
- if [[ "$MEAL_ID" -eq "$HALF_TIME" ]]
- then
- log "FID#$PHILOSOPHER_ID ""---POŁOWA--- Meals consumed: ""$MEALS_CONSUMED"
- echo > "$TABLE_LOCK"
- read line < "$TABLE_LOCK""1"
- log "FID#$PHILOSOPHER_ID ""Barrier is passed."
- fi
- done
- log "FID#$PHILOSOPHER_ID ""___STOP___ Meals consumed: ""$MEALS_CONSUMED"
- }
- random_time() {
- echo "0.""$RANDOM"
- }
- #Scrypt start
- while getopts ":s:f:n:k:r:i:" OPT
- do
- case "$OPT" in
- s)
- FAIL=false
- mkdir -p -- "$OPTARG" || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as table path, , exiting program with exit code 2..."
- exit 2
- else
- TABLE_PATH="$OPTARG"
- fi
- ;;
- f)
- FAIL=false
- is_int "$OPTARG" || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as number of philosopers - a non-integer parameter has been given. Exiting program with exit code 4..."
- exit 4
- fi
- [[ "$OPTARG" -ge "2" ]] || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as number of philosopers - there must be at least 2 philosophers. Exiting program with exit code 5..."
- exit 5
- else
- PHILOSOPHERS_COUNT="$OPTARG"
- fi
- ;;
- n)
- FAIL=false
- is_int "$OPTARG" || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as maximum number meals. Parameter is not an integer. Exiting program with exit code 6..."
- exit 6
- fi
- [[ "$OPTARG" -ge "0" ]] || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as maximum number meals. Parameter must be a positive integer. Exiting program with exit code 7..."
- exit 7
- else
- MAX_MEALS="$OPTARG"
- fi
- ;;
- k)
- FAIL=false
- is_float "$OPTARG" || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as eating time. Parameter is not a floating-point number. Exiting program with exit code 8..."
- exit 8
- fi
- if (( $(echo "$OPTARG<0" | bc) )); then
- FAIL=true
- fi
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as eating time. This parameter cannot be a negative number. Exiting program with exit code 9..."
- exit 9
- else
- EATING_TIME="$OPTARG"
- fi
- ;;
- r)
- FAIL=false
- is_float "$OPTARG" || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as sleeping time. The parameter is not a floating-point number. Exiting program with exit code 10..."
- exit 10
- fi
- if (( $(echo "$OPTARG<0" | bc) )); then
- FAIL=true
- fi
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as sleeping time. The parameter cannot be a negative number. Exiting program with exit code 11..."
- exit 11
- else
- SLEEPING_TIME="$OPTARG"
- fi
- ;;
- i)
- FAIL=false
- is_int "$OPTARG" || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as philosopher ID. The parameter is not an integer. Exiting program with exit code 12..."
- exit 12
- fi
- [[ "$OPTARG" -ge "1" ]] || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as philosopher ID. The parameter cannot be lesser than 1. Exiting program with exit code 13..."
- exit 13
- else
- PHILOSOPHER_ID="$OPTARG"
- LOG_IDENTITY="FID#""$PHILOSOPHER_ID"
- fi
- ;;
- \:)
- log "\`\`""-$OPTARG""'' requires some value. Exiting program with exit code 14..."
- exit 14
- ;;
- \?)
- log "\`\`""-$OPTARG""'' is not a valid argument. Exiting program with exit code 15..."
- exit 15
- ;;
- esac
- done
- if [ ! -d "$TABLE_PATH""stol" ]; then
- mkdir -p "$TABLE_PATH""stol"
- fi
- TABLE_PATH=${TABLE_PATH:-`realpath -- "$TABLE_PATH""stol"`}
- TABLE_PATH=`realpath -- "$TABLE_PATH"`
- PHILOSOPHERS_COUNT=${PHILOSOPHERS_COUNT:-5}
- MAX_MEALS=${MAX_MEALS:-7}
- PHILOSOPHER_ID=${PHILOSOPHER_ID:-0}
- TABLE_LOCK="$TABLE_PATH""/table.lock"
- for i in `seq 1 "$PHILOSOPHERS_COUNT"`
- do
- if [ -f "$TABLE_PATH""stol""/""$i" ]; then
- touch "$TABLE_PATH""stol""/""$i"
- if [ $? -ne 0 ]; then
- log "Failed to create fork $i, exiting program with exit code 16..."
- exit 16;
- fi
- fi
- done
- if [ -f "$TABLE_LOCK" ]; then
- mkfifo "$TABLE_LOCK"
- if [ $? -ne 0 ]; then
- log "Failed to create pipe, exiting program with exit code 3..."
- exit 3;
- fi
- fi
- if [ -f "$TABLE_LOCK""1" ]; then
- mkfifo "$TABLE_LOCK""1"
- if [ $? -ne 0 ]; then
- log "Failed to create pipe, exiting program with exit code 3..."
- exit 3;
- fi
- fi
- a=( $(shuf -e $(seq 1 "$PHILOSOPHERS_COUNT")) )
- for i in "${a[@]}"
- do
- log `hostname`" STARTUJE FILOZOF... "$i" "$TABLE_PATH" "$MAX_MEALS" "$EATING_TIME" "$SLEEPING_TIME""
- run_philosopher "$i" "$TABLE_PATH" "$MAX_MEALS" "$EATING_TIME" "$SLEEPING_TIME" &
- done
- for i in `seq 1 "$PHILOSOPHERS_COUNT"`
- do
- read line < "$TABLE_LOCK"
- done
- for i in `seq 1 "$PHILOSOPHERS_COUNT"`
- do
- echo > "$TABLE_LOCK""1"
- done
- for CPID in `pgrep -P "$$" | xargs`
- do
- wait "$CPID"
- done
- log "___STOP___"
- #Description of all non-zero exit codes:
- #Exit code 2 -- occurs if table with given name could not be created - either another, non-directory file with same name exists within present working directory, or you do not have proper permissions
- # występuje w sytuacji, gdy nie udało się utworzyć stołu o podanej nazwie - istnieje plik regularny o takiej samej nazwie jak zadany stół lub obecny użytkownik nie posiada uprawnień niezbędnych do stworzenia nowego folderu
- #Exit code 3 -- occurs if one or both of the pipes with names table.lock and table.lock1 could not be created - for similar reasons as in case of exit code 2
- # występuje, gdy nie uda się utworzyć któregoś z potoków (o nazwach table.lock i table.lock1) - powody dla których nie udało się tego dokonać mogą być podobne do tych co w przypadku kodu wyjścia 2
- #Exit code 4 -- occurs if -f parameter is not an integer - problem assumes, that number of philosophers is a positive integer greater or equal 2
- # występuje w przypadku, gdy podany parametr -f nie jest liczbą całkowitą - poprawne sformułowanie problemu wymaga, by liczba filozofów była liczbą naturalną niemniejszą niż 2
- #Exit code 5 -- occurs if -f parameter is an integer, but it is lesser than 2 - problem assumes that there are at least 2 philosophers
- # występuje w przypadku, gdy podany parametr -f jest liczbą całkowitą, ale jest mniejszy od 2 - poprawne sformułowanie problemu zakłada, że liczba filozofów jest niemniejsza niż 2
- #Exit code 6 -- occurs if -n parameter, describing number of meals to be eaten by each philosopher is not an integer
- # występuje w sytuacji, gdy parametr -n opisujący liczbę posiłków, które zje każdy z filozofów nie jest liczbą całkowitą
- #Exit code 7 -- occurs if -n parameter is not a positive integer, which is not possible for the correct formulation of the problem
- # występuje w sytuacji, gdy parametr -n nie jest liczbą naturalną dodatnią -- w poprawnie sformułowanym problemie nie jest możliwe, by filozofowie spożyli niedodatnią liczbę posiłków
- #Exit code 8 -- occurs if -k parameter, describing eating time is not a floating-point number
- # występuje w przypadku, gdy parametr -k opisujący czas spożywania posiłku nie jest liczbą zmiennoprzecinkową
- #Exit code 9 -- occurs if -k parameter is a floating-point number, but it is not positive
- # występuje w przypadku, gdy parametr -k jest niedodatnią liczbą zmiennoprzecinkową
- #Exit code 10 -- occurs if -r parameter, describing sleeping time is not a floating-point number
- # występuje w przypadku, gdy parametr -r opisujący czas rozmyślania po posiłku nie jest liczbą zmiennoprzecinkową
- #Exit code 11 -- occurs if -r parameter is a nonpositive floating-point number
- # występuje w przypadku, gdy parametr -r jest liczbą zmiennoprzecinkową niedodatnią
- #Exit code 12 -- occurs if philosopher id parameter -i is not an integer
- # występuje w przypadku, gdy zadeklarowano ID filozofa nie będące liczbą całkowitą (opcja -i)
- #Exit code 13 -- occurs if philosopher id parameter -i is a nonpositive integer
- # występuje w przypadku, gdy zadeklarowano ID filozofa będące liczbą całkowitą mniejszą od 1
- #Exit code 14 -- occurs if some option is obtained without a parameter
- # występuje w przypadku, gdy podana zostanie nazwa opcji obsługiwanej przez skrypt, jednak bez wartości parametru
- #Exit code 15 -- occurs if user gave an option which is not described and irrevelant to dining philosophers problem
- # występuje, gdy użytkownik poda nazwę opcji nieopisanej w skrypcie i niepotrzebnej w problemie ucztujących filozofów
- #Exit code 16 -- occurs if creating one of the forks was not possible -- for similar reasons as in case of exit code 2
- # występuje, gdy nie można utworzyć któregoś z plików widelców -- z przyczyn podobnych jak w przypadku kodu wyjścia 2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement