转载请注明出处: Linux系统运维 http://www.linuxyw.com/linux/Shell/20130403/15.html #创建管道文件 mkfifo "$tmp_fifofile" #把文件描述符6指向管道文件,文件描述符可以使用3-9任意一个即可(除了5),0、1、2、5已有定义,具体可参考关于文件描述符的文章。 EXEC 6<>"$tmp_fifofile" #删除管道文件,其实删不删无所谓,看你自己了。 rm -f $tmp_fifofile #使用一个for循环向管道中输入$SEND_THREAD_NUM个空行;>符号为输出重导向;&符号表示6为文件描述符,也就是说&6表示文件描述符6. for ((i=0;i<$SEND_THREAD_NUM;i++));do echo done >&6 for i in `seq 1 100`;do # 100 次 for 循环开始,也就是说表示100次你的实际应用 read -u6 # 从文件描述符6(即管道)中读取行,每次读一行,由于是管道,读一行,管道中便少一行,每次只能读取一行,注意:如果读完了,便会挂起,直到管道中再次有可读的行。 { echo $i # 打印i,这里代表整个脚本的应用部分,可以替换成你的实际应用。 sleep 3 # 暂停3秒,这里是关键点,其实引入管道模拟多线程的关键就是为了这个暂停的3秒(实际上是微大于3秒的),让系统有个缓冲的时间,起到限制所谓并发的进程数量。 echo >&6 # 再次往管道文件中写入一个空行,为了挂起的for循环能够继续执行。 } & #注意这里要放到后台,也就是说echo $i这个你的应用有13个是几乎同时在后台执行的,为什么是13个呢?当for循环完13次后会挂起,因为管道已经空了,read -u6会暂时挂起,直到管道中有了空行。由于本commands block(即{}中的内容)是放在后台执行的,可以理想的看成这13次循环是同时执行的,大家同时sleep了3秒,而又同时向管道中输入了空行,所以管道在读空之后差不多3秒的时候又瞬时多了13次空行,使得read -u6能够继续读行,for循环得以继续执行。 pid=$! # $!代表在后台执行的最后一个进程。 本文来自linux系统运维:http://www.linuxyw.com/linux/Shell/20130403/15.html |