Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/bash
- # !! 请根据机器承载能力设置 !!
- # 后台任务数数
- N=4000
- CUR_DIR=$(
- cd "$(dirname "$0")" || exit
- pwd
- )
- cd "${CUR_DIR}" || exit
- # 简易日志输出,前面加上当前时间(到毫秒)
- ezlog() {
- dt=$(date +'%T.%3N')
- printf "[${dt}] "$@
- }
- # 命名管道通信
- export concur_fifo="${CUR_DIR}/$$.concur.fifo"
- mkfifo "${concur_fifo}"
- # 输出控制命名管道
- export printer_lock="${CUR_DIR}/$$.printer.lock"
- touch "${printer_lock}"
- exec 200< "$printer_lock"
- # 日志文件,辅助事后排查
- logfile="./output.txt"
- : > "${logfile}"
- # 收尾函数
- # ========
- clean() {
- rm -f "${concur_fifo}"
- rm -f "${printer_lock}"
- }
- # 中断信号处理函数
- # ================
- interrupt() {
- ezlog "Catch ^C signal, exiting.\n"
- clean
- exit 1
- }
- trap interrupt INT
- # 信息统计(消费管道信息)
- {
- done=0
- bonus=0
- servtime=0
- debugfile="${CUR_DIR}/debug.txt"
- : > "${debugfile}"
- while :; do
- # !! 消费侧并不需要锁控制 !!
- # if flock -s -n 200; then
- # 从命名管道读取,管道中可能有多行数据,用 read 一并读入后逐行处理
- IFS=$'\n' read -r -d "" -a lines < "${concur_fifo}"
- # flock -u 200
- for line in "${lines[@]}"; do
- echo "${line}" | tee -a "${debugfile}"
- if [[ $line =~ ([0-9]+)$ ]]; then
- ((servtime += $(grep -Po '\d+$' <<< "${line}")))
- fi
- case $line in
- *服务结束*)
- echo "[INFO] $((++done)) 名技师已完成服务"
- ((done == N)) && break 2
- ;;
- *加钟*)
- ((++bonus))
- ;;
- esac
- done
- # fi
- done
- echo "技师已全部服务完成,服务总时长:$servtime,加钟次数:$bonus"
- } &
- # 后台任务同时进行
- for ((i = 1; i <= N; i++)); do
- {
- exec 200> "$printer_lock"
- service_duration=$((1 + RANDOM % 5))
- # 为防止串行,用文件锁控制写入
- flock 200
- ezlog "%04d号技师开始服务,服务时长:$service_duration\n" $i | tee -a "${concur_fifo}" $logfile 1> /dev/null
- flock -u 200
- sleep $service_duration
- # 是否包含特殊服务
- while :; do
- bonus=$((RANDOM % 2))
- if ((bonus)); then
- bonus_duration=$((1 + RANDOM % 3))
- flock 200
- ezlog "%04d号技师喜提加钟,额外服务时长:$bonus_duration\n" $i | tee -a "${concur_fifo}" $logfile 1> /dev/null
- flock -u 200
- sleep $bonus_duration
- else
- break
- fi
- done
- flock 200
- ezlog "%04d号技师服务结束\n" $i | tee -a "${concur_fifo}" $logfile 1> /dev/null
- flock -u 200
- exec 200>&-
- } &
- done
- # done=0
- # bonus=0
- # servtime=0
- # debugfile="${CUR_DIR}/debug.txt"
- # : > "${debugfile}"
- # while read -r line; do
- # echo "${line}" | tee -a "${debugfile}"
- # if [[ $line =~ ([0-9]+)$ ]]; then
- # ((servtime += $(grep -Po '\d+$' <<< "${line}")))
- # fi
- # case $line in
- # *服务结束*)
- # echo "[INFO] $((++done)) 名技师已完成服务"
- # ((done == N)) && break 2
- # ;;
- # *加钟*)
- # ((++bonus))
- # ;;
- # esac
- # done < "${concur_fifo}"
- wait
- clean
- exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement