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 ]参数的,具体跟操作系统有关。以上原因为个人推测。
本文永久更新地址://m.ajphoenix.com/linux/21300.html