#!/bin/bash
#by inmoonlight@163.com
#下面的代碼控制并發(fā)數(shù)。其實是利用令牌原理實現(xiàn)
#一個線程要運行,首先要拿到令牌在該代碼中即read一行數(shù)據(jù),讀取不到就會暫停,否則就拿到數(shù)據(jù)就運行命令,當(dāng)完成后將令牌放回
#將令牌放回即再在管道文件中寫入一行數(shù)據(jù),這里的數(shù)據(jù)是換行符,echo >&4。這樣另外的線程就可以再讀該數(shù)據(jù)(拿到令牌)并運行
#!/bin/bash
tmpf=$0.fifo #命名管道
mkfifo $tmpf #創(chuàng)建管道
exec 4<>$tmpf #創(chuàng)建文件描述符4,以讀寫方式操作管道
rm $tmpf #刪除創(chuàng)建的管道
thred=4 #指定并發(fā)數(shù)
seq=(1 2 3 4 5 6 7 8 9 21 22 23 24 25 31 32 33 34 35) #創(chuàng)建線程的任務(wù)列表
#為并發(fā)線程創(chuàng)建相應(yīng)個數(shù)的占位
{
for (( i = 1;i<=${thred};i++ ))
do
echo; #因read命令讀取一行,而echo默認(rèn)輸出換行符,所以為每個線程輸出占位換行
done
} >&4 #將占位寫入管道(輸出給文件描述符4 --> &4 的作用,如果不加 "&" 會被bash解釋為文件名)
for id in ${seq[*]} #從任務(wù)列表"seq"按順序獲取任務(wù),或:for id in ${seq}
do
read #讀取一行,即fd4中的一個占位符
(./command ${id}; echo >&4 ) & #在后臺執(zhí)行任務(wù)command并將任務(wù)${id}賦予當(dāng)前任務(wù)command;執(zhí)行完成后在fd4中寫入一個換行占位 ,"&" 即將其之前部分放入后臺實現(xiàn)并行執(zhí)行
done <&4 #指定fd4為整個for的stdin(讀取fd4的占位信息)
wait #阻塞等待所有在此腳本中的后臺任務(wù):"{.....}&" 完成
exec 4>&- #關(guān)閉管道
#以上流程中read、echo對fd4的交替寫和讀是并發(fā)處理的關(guān)鍵!,可以想象若read讀取不到fd4中數(shù)據(jù)時將等待fd4
http://www.rzrgm.cn/bluevitality/p/6524147.html