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

程序逻辑相当于造一个令牌桶,进程从中拿令牌,获取到令牌才可以执行,否则就阻塞
程序输出如下:

posted @ 2017-06-14 14:43  酱油ops  阅读(1945)  评论(0编辑  收藏  举报