shell多進程2-控制進程並發數


前面寫了一篇shell多進程的文章,多進程實現起來非常簡單,但是當有大量任務,如有一百個很大的日志文件需要分析
此時若同時並行100個進程,那io肯定要爆,所以必須要控制並發數

linux 有兩種管道:匿名管道和命名管道
匿名管道即常用的'|',命名管道可以使用mkfifo命令創建
管道有一個特性:只有讀寫同時存在時,數據才可以在管道中傳遞,否則讀或者寫操作將會被阻塞
下面的腳本中即利用管道的此特性來控制並發數

# worker模擬一些耗時函數
function worker() {
    echo $1
    sleep 10
    echo "$1"":done"
}
# 創建管道,並關聯文件描述符,最后刪除管道文件是避免腳本退出后有遺留垃圾文件,影響下一次運行
# 刪除管道文件后,因為程序還在運行中,管道還是可用的,此時用lsof |grep $tmpfifo可以看到delete狀態的管道文件,等程序運行完結束后,系統會自動清理這個文件
tmpfifo=/tmp/tmp.fifo
mkfifo $tmpfifo
exec 1000<>$tmpfifo
rm -f $tmpfifo
# 先向管道中寫入3個空行,控制並發數量,其實此時並沒有寫入而是等下面的read操作時才實際寫入。
for ((i=1;i<=3;i++))
do
 echo "">&1000 &
done
# read -u從文件描述符中讀取一行,然后執行相關操作,若讀不到則會阻塞在這里,從而實現進程控制
for ((j=1;j<=10;j++))
do
 read -u1000
 {
 worker $j
 # 執行完成后寫回管道
 echo "">&1000
} &
done
wait

程序邏輯相當於造一個令牌桶,進程從中拿令牌,獲取到令牌才可以執行,否則就阻塞
程序輸出如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM