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 ]参数的,具体跟操做系统有关。以上缘由为我的推测,若是有人可以知道真正的缘由,还请予以告知,哈哈哈多线程