关于Linux shell多线程控制无效的bug

    shell的多线程编程代码网上有不少,示例代码以下:shell

thead_num=5 #设置线程数,在这里所谓的线程,其实就是几乎同时放入后台(使用&)执行的进程。 
tmp_fifo_file="/tmp/$$.fifo"  #以进程ID号命名管道文件
mkfifo $tmp_fifo_file   #建立临时管道文件
exec 6<>$tmp_fifo_file  #以读写方式打开tmp_fifo_file管道文件,文件描述符为6,也能够取3-9任意描述符
rm -f $tmp_fifo_file    #删除临时管道文件,也可不删除

for ((i=0;i<$thead_num;i++))   #利用for循环向管道中输入并发数量的空行
do
        echo ""  #输出空行
done >&6  #输出重导向到定义的文件描述符6上

for i in $ip  #循环全部要执行的服务器
do
        read -u6  #从管道中读取行,每次一行,全部行读取完毕后执行挂起,直到管道有空闲的行
                {
                        ......  #线程内的执行代码(若是须要执行时间较长,bug就可能来了)
                        echo "" >&6  #再写入一个空行,使挂起的循环继续执行
                }&  #放入后台执行
done
wait  #等待全部后台进程执行完成
exec 6>&-  #删除文件描述符

    

    问题:以前遇到过一个很惊艳的bug,在用shell写多线程时,线程数量在达到设定的数量以后继续不断增长,多线程控制是无效的,这bug也简直了,我明明给了5个并发,这丫的愣是建立了几十个进程,结果发现查了好多资料,愣是没找到缘由,后来发现是个人每一个线程处理块的执行时间都比较久,结果,正在 执行的进程还没执行结束,也就是管道中尚未新的空闲的行,系统就新建立了一个新的进程,这看似很不合逻辑。编程

    解决办法:用“read -u6 -t86400”替换“read -u6”,-t后面的数字表示时间,单位是秒服务器

    缘由:具体权威的缘由不太肯定,根据已知的资料,推测是由于read -u6这条命令的[ -t ]参数是有默认值的,在个人系统里 ,好像是3min,也就是说,若是3min以后,后台进程依然没有执行结束,系统会认为该进程已经执行完毕,继续分配进程。须要特别说明的是,不是全部的系统都须要指定这个[ -t ]参数的,具体跟操做系统有关。以上缘由为我的推测,若是有人可以知道真正的缘由,还请予以告知,哈哈哈多线程

相关文章
相关标签/搜索