Advertisement
shinemic

bash_jobs.sh

Sep 3rd, 2023 (edited)
851
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 3.55 KB | None | 0 0
  1. #!/usr/bin/bash
  2.  
  3. # !! 请根据机器承载能力设置 !!
  4. # 后台任务数数
  5. N=4000
  6.  
  7. CUR_DIR=$(
  8.     cd "$(dirname "$0")" || exit
  9.     pwd
  10. )
  11. cd "${CUR_DIR}" || exit
  12.  
  13. # 简易日志输出,前面加上当前时间(到毫秒)
  14. ezlog() {
  15.     dt=$(date +'%T.%3N')
  16.     printf "[${dt}] "$@
  17. }
  18.  
  19. # 命名管道通信
  20. export concur_fifo="${CUR_DIR}/$$.concur.fifo"
  21. mkfifo "${concur_fifo}"
  22.  
  23. # 输出控制命名管道
  24. export printer_lock="${CUR_DIR}/$$.printer.lock"
  25. touch "${printer_lock}"
  26. exec 200< "$printer_lock"
  27.  
  28. # 日志文件,辅助事后排查
  29. logfile="./output.txt"
  30. : > "${logfile}"
  31.  
  32. # 收尾函数
  33. # ========
  34. clean() {
  35.     rm -f "${concur_fifo}"
  36.     rm -f "${printer_lock}"
  37. }
  38.  
  39. # 中断信号处理函数
  40. # ================
  41. interrupt() {
  42.     ezlog "Catch ^C signal, exiting.\n"
  43.     clean
  44.     exit 1
  45. }
  46.  
  47. trap interrupt INT
  48.  
  49. # 信息统计(消费管道信息)
  50. {
  51.     done=0
  52.     bonus=0
  53.     servtime=0
  54.     debugfile="${CUR_DIR}/debug.txt"
  55.     : > "${debugfile}"
  56.     while :; do
  57.         # !! 消费侧并不需要锁控制 !!
  58.         # if flock -s -n 200; then
  59.         # 从命名管道读取,管道中可能有多行数据,用 read 一并读入后逐行处理
  60.         IFS=$'\n' read -r -d "" -a lines < "${concur_fifo}"
  61.         # flock -u 200
  62.         for line in "${lines[@]}"; do
  63.             echo "${line}" | tee -a "${debugfile}"
  64.             if [[ $line =~ ([0-9]+)$ ]]; then
  65.                 ((servtime += $(grep -Po '\d+$' <<< "${line}")))
  66.             fi
  67.             case $line in
  68.                 *服务结束*)
  69.                     echo "[INFO] $((++done)) 名技师已完成服务"
  70.                     ((done == N)) && break 2
  71.                     ;;
  72.                 *加钟*)
  73.                     ((++bonus))
  74.                     ;;
  75.             esac
  76.         done
  77.         # fi
  78.     done
  79.  
  80.     echo "技师已全部服务完成,服务总时长:$servtime,加钟次数:$bonus"
  81. } &
  82.  
  83. # 后台任务同时进行
  84. for ((i = 1; i <= N; i++)); do
  85.     {
  86.         exec 200> "$printer_lock"
  87.         service_duration=$((1 + RANDOM % 5))
  88.  
  89.         # 为防止串行,用文件锁控制写入
  90.         flock 200
  91.         ezlog "%04d号技师开始服务,服务时长:$service_duration\n" $i | tee -a "${concur_fifo}" $logfile 1> /dev/null
  92.         flock -u 200
  93.         sleep $service_duration
  94.  
  95.         # 是否包含特殊服务
  96.         while :; do
  97.             bonus=$((RANDOM % 2))
  98.             if ((bonus)); then
  99.                 bonus_duration=$((1 + RANDOM % 3))
  100.                 flock 200
  101.                 ezlog "%04d号技师喜提加钟,额外服务时长:$bonus_duration\n" $i | tee -a "${concur_fifo}" $logfile 1> /dev/null
  102.                 flock -u 200
  103.                 sleep $bonus_duration
  104.             else
  105.                 break
  106.             fi
  107.         done
  108.  
  109.         flock 200
  110.         ezlog "%04d号技师服务结束\n" $i | tee -a "${concur_fifo}" $logfile 1> /dev/null
  111.         flock -u 200
  112.  
  113.         exec 200>&-
  114.     } &
  115. done
  116.  
  117. # done=0
  118. # bonus=0
  119. # servtime=0
  120. # debugfile="${CUR_DIR}/debug.txt"
  121. # : > "${debugfile}"
  122. # while read -r line; do
  123. #     echo "${line}" | tee -a "${debugfile}"
  124. #     if [[ $line =~ ([0-9]+)$ ]]; then
  125. #         ((servtime += $(grep -Po '\d+$' <<< "${line}")))
  126. #     fi
  127. #     case $line in
  128. #         *服务结束*)
  129. #             echo "[INFO] $((++done)) 名技师已完成服务"
  130. #             ((done == N)) && break 2
  131. #             ;;
  132. #         *加钟*)
  133. #             ((++bonus))
  134. #             ;;
  135. #     esac
  136. # done < "${concur_fifo}"
  137.  
  138. wait
  139.  
  140. clean
  141. exit 0
  142.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement