Advertisement
PanaPatryk44

uruchom.sh RC1

Jun 19th, 2017
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.30 KB | None | 0 0
  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. local PHILOSOPHER_ID=$1
  30. local TABLE_PATH=$2
  31. local MAX_MEALS=$3
  32. local EATING_TIME=$4
  33. local SLEEPING_TIME=$5
  34.  
  35.  
  36. MESSAGE=""
  37. MESSAGE="$MESSAGE""Script file: "`realpath -- "$0"`"; "
  38.  
  39. if [[ "$PHILOSOPHER_ID" -eq "$PHILOSOPHERS_COUNT" ]]
  40. then
  41. FORK_B="$PHILOSOPHER_ID"
  42. FORK_A="1"
  43. else
  44. FORK_A="$PHILOSOPHER_ID"
  45. FORK_B=$[PHILOSOPHER_ID+1]
  46. fi
  47. FORK_A_PATH=`realpath -- "$TABLE_PATH""/""$FORK_A"`
  48. FORK_B_PATH=`realpath -- "$TABLE_PATH""/""$FORK_B"`
  49.  
  50. MESSAGE="$MESSAGE""Table path: \`\`""$TABLE_PATH""''; "
  51. if [[ "$PHILOSOPHER_ID" -ne "0" ]]
  52. then
  53. MESSAGE="$MESSAGE""Primary fork: ""$FORK_A_PATH""; "
  54. MESSAGE="$MESSAGE""Secondary fork: ""$FORK_B_PATH""; "
  55. fi
  56. MESSAGE="$MESSAGE""Philosophers count: ""$PHILOSOPHERS_COUNT""; "
  57. MESSAGE="$MESSAGE""Maximum meals: ""$MAX_MEALS""; "
  58.  
  59. if [[ -z $EATING_TIME ]]
  60. then
  61. MESSAGE="$MESSAGE""Eating time: randomized; "
  62. else
  63. MESSAGE="$MESSAGE""Eating time: ""$EATING_TIME""s; "
  64. fi
  65.  
  66. if [[ -z $SLEEPING_TIME ]]
  67. then
  68. MESSAGE="$MESSAGE""Sleeping time: randomized; "
  69. else
  70. MESSAGE="$MESSAGE""Sleeping time: ""$SLEEPING_TIME""s; "
  71. fi
  72.  
  73. log "FID#$PHILOSOPHER_ID ""^^^START^^^ ""$MESSAGE"
  74.  
  75. HALF_TIME=$[(MAX_MEALS+1)/2]
  76. MEALS_CONSUMED=0
  77.  
  78. for MEAL_ID in `seq 1 "$MAX_MEALS"`
  79. do
  80. ACTUAL_EATING_TIME=${EATING_TIME:-`random_time`}
  81. ACTUAL_SLEEPING_TIME=${SLEEPING_TIME:-`random_time`}
  82.  
  83. log "FID#$PHILOSOPHER_ID ""FID#$PHILOSOPHER_ID ""Trying to acquire Fork WID#""$FORK_A"
  84. (
  85. flock -x 9
  86. log "FID#$PHILOSOPHER_ID ""Fork WID#""$FORK_A"" acquired successfully (exclusive lock put on fork "$FORK_A")"
  87.  
  88. log "FID#$PHILOSOPHER_ID ""Trying to acquire Fork WID#""$FORK_B (trying to put exclusive lock on fork "$FORK_B")"
  89. (
  90. flock -x 10
  91. log "FID#$PHILOSOPHER_ID ""Fork WID#""$FORK_B"" acquired successfully (exclusive lock put on fork "$FORK_B")"
  92.  
  93. log "FID#$PHILOSOPHER_ID ""Eating Meal#""$MEAL_ID "" started, it will take ""$ACTUAL_EATING_TIME""s"
  94. sleep "$ACTUAL_EATING_TIME"
  95. log "FID#$PHILOSOPHER_ID ""Eating Meal#""$MEAL_ID "" finished"
  96. ) 10>"$FORK_B_PATH"
  97. log "FID#$PHILOSOPHER_ID ""Putting Fork WID#""$FORK_A"" back (exclusive lock dropped from fork WID#"$FORK_A")"
  98.  
  99. ) 9>"$FORK_A_PATH"
  100. log "FID#$PHILOSOPHER_ID ""Putting Fork WID#""$FORK_B"" back (exclusive lock dropped from fork WID#"$FORK_B")"
  101.  
  102. MEALS_CONSUMED=$[MEALS_CONSUMED+1]
  103.  
  104. log "FID#$PHILOSOPHER_ID ""Sleeping after Meal#""$MEAL_ID "" started, it will take ""$ACTUAL_SLEEPING_TIME""s"
  105. sleep "$ACTUAL_SLEEPING_TIME"
  106. log "FID#$PHILOSOPHER_ID ""Sleeping after Meal#""$MEAL_ID "" finished"
  107.  
  108. if [[ "$MEAL_ID" -eq "$HALF_TIME" ]]
  109. then
  110. log "FID#$PHILOSOPHER_ID ""---POŁOWA--- Meals consumed: ""$MEALS_CONSUMED"
  111. echo > "$TABLE_LOCK"
  112. read line < "$TABLE_LOCK""1"
  113. log "FID#$PHILOSOPHER_ID ""Barrier is passed."
  114.  
  115. fi
  116. done
  117.  
  118. log "FID#$PHILOSOPHER_ID ""___STOP___ Meals consumed: ""$MEALS_CONSUMED"
  119. }
  120.  
  121.  
  122.  
  123. random_time() {
  124. echo "0.""$RANDOM"
  125. }
  126.  
  127.  
  128.  
  129.  
  130. #Scrypt start
  131. while getopts ":s:f:n:k:r:i:" OPT
  132. do
  133. case "$OPT" in
  134. s)
  135. FAIL=false
  136. mkdir -p -- "$OPTARG" || FAIL=true
  137.  
  138. if "$FAIL"
  139. then
  140. log "Cannot parse \`\`""$OPTARG""'' as table path."
  141. exit 2
  142. else
  143. TABLE_PATH="$OPTARG"
  144. fi
  145. ;;
  146. f)
  147. FAIL=false
  148. is_int "$OPTARG" || FAIL=true
  149. if "$FAIL"
  150. then
  151. log "Cannot parse \`\`""$OPTARG""'' as number of philosopers - a non-integer parameter has been given."
  152. exit 4
  153. fi
  154.  
  155. [[ "$OPTARG" -ge "2" ]] || FAIL=true
  156.  
  157. if "$FAIL"
  158. then
  159. log "Cannot parse \`\`""$OPTARG""'' as number of philosopers - there must be at least 2 philosophers."
  160. exit 5
  161. else
  162. PHILOSOPHERS_COUNT="$OPTARG"
  163. fi
  164. ;;
  165. n)
  166. FAIL=false
  167. is_int "$OPTARG" || FAIL=true
  168.  
  169. if "$FAIL"
  170. then
  171. log "Cannot parse \`\`""$OPTARG""'' as maximum number meals. Parameter is not an integer"
  172. exit 6
  173. fi
  174.  
  175. [[ "$OPTARG" -ge "0" ]] || FAIL=true
  176.  
  177. if "$FAIL"
  178. then
  179. log "Cannot parse \`\`""$OPTARG""'' as maximum number meals. Parameter must be a positive integer"
  180. exit 7
  181. else
  182. MAX_MEALS="$OPTARG"
  183. fi
  184. ;;
  185. k)
  186. FAIL=false
  187. is_float "$OPTARG" || FAIL=true
  188.  
  189. if "$FAIL"
  190. then
  191. log "Cannot parse \`\`""$OPTARG""'' as eating time. Parameter is not a floating-point number."
  192. exit 8
  193. fi
  194.  
  195. if (( $(echo "$OPTARG<0" | bc) )); then
  196. FAIL=true
  197. fi
  198.  
  199. if "$FAIL"
  200. then
  201. log "Cannot parse \`\`""$OPTARG""'' as eating time. This parameter cannot be a negative number."
  202. exit 9
  203. else
  204. EATING_TIME="$OPTARG"
  205. fi
  206. ;;
  207. r)
  208. FAIL=false
  209. is_float "$OPTARG" || FAIL=true
  210. if "$FAIL"
  211. then
  212. log "Cannot parse \`\`""$OPTARG""'' as sleeping time. The parameter is not a floating-point number."
  213. exit 10
  214. fi
  215.  
  216. if (( $(echo "$OPTARG<0" | bc) )); then
  217. FAIL=true
  218. fi
  219. if "$FAIL"
  220. then
  221. log "Cannot parse \`\`""$OPTARG""'' as sleeping time. The parameter cannot be a negative number."
  222. exit 11
  223. else
  224. SLEEPING_TIME="$OPTARG"
  225. fi
  226. ;;
  227. i)
  228. FAIL=false
  229. is_int "$OPTARG" || FAIL=true
  230. if "$FAIL"
  231. then
  232. log "Cannot parse \`\`""$OPTARG""'' as philosopher ID. The parameter is not an integer."
  233. exit 12
  234. fi
  235.  
  236. [[ "$OPTARG" -ge "1" ]] || FAIL=true
  237.  
  238. if "$FAIL"
  239. then
  240. log "Cannot parse \`\`""$OPTARG""'' as philosopher ID. The parameter cannot be lesser than 1"
  241. exit 13
  242. else
  243. PHILOSOPHER_ID="$OPTARG"
  244. LOG_IDENTITY="FID#""$PHILOSOPHER_ID"
  245. fi
  246. ;;
  247. \:)
  248. log "\`\`""-$OPTARG""'' requires some value."
  249. exit 14
  250. ;;
  251. \?)
  252. log "\`\`""-$OPTARG""'' is not a valid argument."
  253. exit 15
  254. ;;
  255. esac
  256. done
  257.  
  258.  
  259.  
  260.  
  261.  
  262. TABLE_PATH=${TABLE_PATH:-`realpath -- "$TABLE_PATH""stolik"`}
  263. TABLE_PATH=`realpath -- "$TABLE_PATH"`
  264. if [ ! -d "$TABLE_PATH" ]; then
  265. mkdir -p "$TABLE_PATH"
  266.  
  267. fi
  268. PHILOSOPHERS_COUNT=${PHILOSOPHERS_COUNT:-5}
  269. MAX_MEALS=${MAX_MEALS:-7}
  270. PHILOSOPHER_ID=${PHILOSOPHER_ID:-0}
  271. TABLE_LOCK="$TABLE_PATH""/""table.lock"
  272.  
  273.  
  274. for i in `seq 1 "$PHILOSOPHERS_COUNT"`
  275. do
  276. if [ -f "$TABLE_PATH""/""$i" ]; then
  277. touch "$TABLE_PATH""/""$i"
  278. if [ $? -ne 0 ]; then
  279. log "Failed to create fork $i, exiting program with exit code 16..."
  280. exit 3;
  281. fi
  282.  
  283. fi
  284. done
  285.  
  286. if [ -c "$TABLE_LOCK" ]; then
  287. mkfifo "$TABLE_LOCK"
  288. if [ $? -ne 0 ]; then
  289. log "Failed to create pipe, exiting program with exit code 3..."
  290. exit 3;
  291. fi
  292. fi
  293. if [ -c "$TABLE_LOCK""1" ]; then
  294. mkfifo "$TABLE_LOCK""1"
  295. if [ $? -ne 0 ]; then
  296. log "Failed to create pipe, exiting program with exit code 3..."
  297. exit 3;
  298. fi
  299. fi
  300. a=( $(shuf -e $(seq 1 "$PHILOSOPHERS_COUNT")) )
  301. for i in "${a[@]}"
  302. do
  303.  
  304. log `hostname`" STARTUJE FILOZOF... "$i" "$TABLE_PATH" "$MAX_MEALS" "$EATING_TIME" "$SLEEPING_TIME""
  305. run_philosopher "$i" "$TABLE_PATH" "$MAX_MEALS" "$EATING_TIME" "$SLEEPING_TIME" &
  306. done
  307. for i in `seq 1 "$PHILOSOPHERS_COUNT"`
  308. do
  309. read line < "$TABLE_LOCK"
  310. done
  311. for i in `seq 1 "$PHILOSOPHERS_COUNT"`
  312. do
  313. echo > "$TABLE_LOCK""1"
  314. done
  315.  
  316. for CPID in `pgrep -P "$$" | xargs`
  317. do
  318. wait "$CPID"
  319. done
  320.  
  321. log "___STOP___"
  322.  
  323. #Description of all non-zero exit codes:
  324. #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
  325. # 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
  326. #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
  327. # 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
  328. #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
  329. # 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
  330. #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
  331. # 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
  332. #Exit code 6 -- occurs if -n parameter, describing number of meals to be eaten by each philosopher is not an integer
  333. # 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ą
  334. #Exit code 7 -- occurs if -n parameter is not a positive integer, which is not possible for the correct formulation of the problem
  335. # 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
  336. #Exit code 8 -- occurs if -k parameter, describing eating time is not a floating-point number
  337. # występuje w przypadku, gdy parametr -k opisujący czas spożywania posiłku nie jest liczbą zmiennoprzecinkową
  338. #Exit code 9 -- occurs if -k parameter is a floating-point number, but it is not positive
  339. # występuje w przypadku, gdy parametr -k jest niedodatnią liczbą zmiennoprzecinkową
  340. #Exit code 10 -- occurs if -r parameter, describing sleeping time is not a floating-point number
  341. # występuje w przypadku, gdy parametr -r opisujący czas rozmyślania po posiłku nie jest liczbą zmiennoprzecinkową
  342. #Exit code 11 -- occurs if -r parameter is a nonpositive floating-point number
  343. # występuje w przypadku, gdy parametr -r jest liczbą zmiennoprzecinkową niedodatnią
  344. #Exit code 12 -- occurs if philosopher id parameter -i is not an integer
  345. # występuje w przypadku, gdy zadeklarowano ID filozofa nie będące liczbą całkowitą (opcja -i)
  346. #Exit code 13 -- occurs if philosopher id parameter -i is a nonpositive integer
  347. # występuje w przypadku, gdy zadeklarowano ID filozofa będące liczbą całkowitą mniejszą od 1
  348. #Exit code 14 -- occurs if some option is obtained without a parameter
  349. # występuje w przypadku, gdy podana zostanie nazwa opcji obsługiwanej przez skrypt, jednak bez wartości parametru
  350. #Exit code 15 -- occurs if user gave an option which is not described and irrevelant to dining philosophers problem
  351. # występuje, gdy użytkownik poda nazwę opcji nieopisanej w skrypcie i niepotrzebnej w problemie ucztujących filozofów
  352. #Exit code 16 -- occurs if creating one of the forks was not possible -- for similar reasons as in case of exit code 2
  353. # 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