linux shell 实现多线程

在bash中,使用后台任务来实现任务的“多进程化”。在不加控制的模式下,不管有多少任务,全部都后台执行。也就是说,在这种情况下,有多少任务就有多少“进程”在同时执行。我们就先实现第一种情况:

实例一:正常情况脚本

 

linux <wbr>shell <wbr>实现多线程 # !/bin/bash
linux <wbr>shell <wbr>实现多线程

linux <wbr>shell <wbr>实现多线程
for  ((i = 0 ;i < 5 ;i ++ )); do
linux <wbr>shell <wbr>实现多线程        {
linux <wbr>shell <wbr>实现多线程                
sleep   3 ;echo  1 >> aa  &&  echo  " done! "
linux <wbr>shell <wbr>实现多线程        
linux <wbr>shell <wbr>实现多线程done
linux <wbr>shell <wbr>实现多线程
wait
linux <wbr>shell <wbr>实现多线程cat aa
| wc  - l
linux <wbr>shell <wbr>实现多线程rm aa

 

这种情况下,程序顺序执行,每个循环3s,共需15s左右。

 

linux <wbr>shell <wbr>实现多线程 time  bash test . sh 
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程
5
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程real    0m15
. 030s
linux <wbr>shell <wbr>实现多线程user    0m0
. 002s
linux <wbr>shell <wbr>实现多线程sys     0m0
. 003s

 

实例二:“多进程”实现

 

linux <wbr>shell <wbr>实现多线程 # !/bin/bash
linux <wbr>shell <wbr>实现多线程

linux <wbr>shell <wbr>实现多线程
for  ((i = 0 ;i < 5 ;i ++ )); do
linux <wbr>shell <wbr>实现多线程        {
linux <wbr>shell <wbr>实现多线程                
sleep   3 ;echo  1 >> aa  &&  echo  " done! "
linux <wbr>shell <wbr>实现多线程        
&
linux <wbr>shell <wbr>实现多线程done
linux <wbr>shell <wbr>实现多线程
wait
linux <wbr>shell <wbr>实现多线程cat aa
| wc  - l
linux <wbr>shell <wbr>实现多线程rm aa

 

这个实例实际上就在上面基础上多加了一个后台执行&符号,此时应该是5个循环任务并发执行,最后需要3s左右时间。

 

linux <wbr>shell <wbr>实现多线程 time  bash test . sh 
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程done
!
linux <wbr>shell <wbr>实现多线程
5
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程real    0m3
. 011s
linux <wbr>shell <wbr>实现多线程user    0m0
. 002s
linux <wbr>shell <wbr>实现多线程sys     0m0
. 004s

 

效果非常明显。

这里需要说明一下wait的左右。wait是等待前面的后台任务全部完成才往下执行,否则程序本身是不会等待的,这样对后面依赖前面任务结果的命令来说就可能出错。例如上面wc -l的命令就报错:不存在aa这个文件。

wait命令的官方解释如下:

 

linux <wbr>shell <wbr>实现多线程              wait  [n]
linux <wbr>shell <wbr>实现多线程                            Wait for the specified process and return its termination status.  may be process ID or   job  specification; if job spec is given, all processes in that job's pipeline are waited for.  If is not given, all currently active child processes are waited for, and the return status is zero.  If   specifies   non-existentprocess  or job, the return status is 127.  Otherwise, the return status is the exit status of the last processor job waited for.

 

以上所讲的实例都是进程数目不可控制的情况,下面描述如何准确控制并发的进程数目。

 

linux <wbr>shell <wbr>实现多线程 # !/bin/bash
linux <wbr>shell <wbr>实现多线程2006-7-12, by wwy
linux <wbr>shell <wbr>实现多线程#———————————————————————————–
linux <wbr>shell <wbr>实现多线程此例子说明了一种用wait、read命令模拟多线程的一种技巧
linux <wbr>shell <wbr>实现多线程此技巧往往用于多主机检查,比如ssh登录、ping等等这种单进程比较慢而不耗费cpu的情况
linux <wbr>shell <wbr>实现多线程还说明了多线程的控制
linux <wbr>shell <wbr>实现多线程#———————————————————————————–

linux <wbr>shell <wbr>实现多线程

linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程function a_sub 
#  此处定义一个函数,作为一个线程(子进程)
linux <wbr>shell <wbr>实现多线程
sleep   3   #  线程的作用是sleep 3s
linux <wbr>shell <wbr>实现多线程
}
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程tmp_fifofile
= " /tmp/$$.fifo "
linux <wbr>shell <wbr>实现多线程mkfifo 
$tmp_fifofile        #  新建一个fifo类型的文件
linux <wbr>shell <wbr>实现多线程
exec   6 <> $tmp_fifofile        #  将fd6指向fifo类型
linux <wbr>shell <wbr>实现多线程
rm  $tmp_fifofile
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程thread
= 15   #  此处定义线程数
linux <wbr>shell <wbr>实现多线程
for  ((i = 0 ;i < $thread ;i ++ )); do  
linux <wbr>shell <wbr>实现多线程echo
linux <wbr>shell <wbr>实现多线程done 
>& 6   #  事实上就是在fd6中放置了$thread个回车符
linux <wbr>shell <wbr>实现多线程

linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程
for  ((i = 0 ;i < 50 ;i ++ )); do   #  50次循环,可以理解为50个主机,或其他
linux <wbr>shell <wbr>实现多线程

linux <wbr>shell <wbr>实现多线程
read   - u6 
linux <wbr>shell <wbr>实现多线程
#  一个read -u6命令执行一次,就从fd6中减去一个回车符,然后向下执行,
linux <wbr>shell <wbr>实现多线程fd6中没有回车符的时候,就停在这了,从而实现了线程数量控制

linux <wbr>shell <wbr>实现多线程

linux <wbr>shell <wbr>实现多线程
#  此处子进程开始执行,被放到后台
linux <wbr>shell <wbr>实现多线程
      a_sub  &&   #  此处可以用来判断子进程的逻辑
linux <wbr>shell <wbr>实现多线程
       echo  " a_sub is finished "
linux <wbr>shell <wbr>实现多线程      
||  {
linux <wbr>shell <wbr>实现多线程       echo 
" sub error "
linux <wbr>shell <wbr>实现多线程      }
linux <wbr>shell <wbr>实现多线程      echo 
>& 6   #  当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
linux <wbr>shell <wbr>实现多线程
&
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程done
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程
wait   #  等待所有的后台子进程结束
linux <wbr>shell <wbr>实现多线程
exec   6 >&-   #  关闭df6
linux <wbr>shell <wbr>实现多线程

linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程
exit   0
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程
linux <wbr>shell <wbr>实现多线程

 

sleep 3s,线程数为15,一共循环50次,所以,此脚本一共的执行时间大约为12秒

即:
15×3=45, 所以 3 x 3s = 9s
(50-45=5)<15, 所以 1 x 3s = 3s
所以 9s + 3s = 12s

$ time ./multithread.sh >/dev/null

real       0m12.025s
user       0m0.020s
sys        0m0.064s

而当不使用多线程技巧的时候,执行时间为:50 x 3s = 150s。

此程序中的命令

linux <wbr>shell <wbr>实现多线程 mkfifo tmpfile

和linux中的命令

linux <wbr>shell <wbr>实现多线程 mknod tmpfile p

效果相同。区别是mkfifo为POSIX标准,因此推荐使用它。该命令创建了一个先入先出的管道文件,并为其分配文件标志符6。管道文件是进程之间通信的一种方式,注意这一句很重要

linux <wbr>shell <wbr>实现多线程 exec   6 <> $tmp_fifofile        #  将fd6指向fifo类型

如果没有这句,在向文件$tmp_fifofile或者&6写入数据时,程序会被阻塞,直到有read读出了管道文件中的数据为止。而执行了上面这一句后就可以在程序运行期间不断向fifo类型的文件写入数据而不会阻塞,并且数据会被保存下来以供read程序读出。



除非注明,本站文章均为原创,转载请以链接形式标明本文地址。
本文地址: http://www.linuxschool.net/linux-shell-bash-mp.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值