shell 中用管道模拟多线程

shell 中用管道模拟多线程

这里以两个例子来对比多线程和单进程

单线程的例子

# config.txt在这个例子和多线程的例子中都会用到
[root@ns_10.2.1.242 test]$ cat config.txt 
1
2
3
4
1
2
3
4

# 下面的代码,是从config.txt中读取配置,然后sleep一定时间,然后打印sleep 的时间长度,
# 注意 while从文本读取数据,是逐行读取的
[root@ns_10.2.1.242 test]$ cat while.sh 
while read line
do
    sleep $line && echo "$line success"
done < config.txt

# 这个脚本,消耗了20秒,结果如下:
[root@ns_10.2.1.242 test]$ time sh while.sh
1 success
2 success
3 success
4 success
1 success
2 success
3 success
4 success

real    0m20.011s
user    0m0.000s
sys     0m0.004s

多线程的例子:

# config.txt在这个例子和多线程的例子中都会用到
[root@ns_10.2.1.242 test]$ cat config.txt 
1
2
3
4
1
2
3
4

# 多线程的代码,如下
[root@ns_10.2.1.242 test]$ cat p3.sh 
#!bash
# 2014-12-5
# --------------------
#  此例子说明了一种用wait、read命令模拟多线程的一种技巧
#  此技巧往往用于多主机检查,比如ssh登录、ping等等这种单进程比较慢而不耗费cpu的情况
# -------------------------
operation(){
    sleep $1
}

tmp_fifofile=/tmp/$$.fifo
#echo $tmp_fifofile

mkfifo $tmp_fifofile # 新建一个fifo的管道文件
exec 6<>$tmp_fifofile # 绑定fd6
rm $tmp_fifofile

# 这里是向管道添加了$thread个空行
THREAD=3 # 线程数,可以改变
for i in $(seq 0 $THREAD);do
    echo
done >&6

CONFIG_FILE=config.txt
# 修改这个脚本到生成环境,主要是修改operation和CONFIG_FILE配置
# 每次读取一行数据
while read line
do
    # 一个read -u6命令执行一次,就从fd6中减去一个回车符,然后向下执行,
    # fd6 中没有回车符的时候,就停在这了,从而实现了线程数量控制
    read -u6

    {
       # 操作成功,记录到成功日志,修改echo
       # 操作失败,记录到错误日志
       operation  $line && echo " $line success" || echo "$line error"

       # 当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
       echo  >&6
    } & # 后台执行,这里的 &是非常重要的,同时有$THREAD个后台进程 

done < ${CONFIG_FILE}


wait # 等待所有的后台子进程结束
exec 6>&- # 关闭df6
exit 0

# 脚本的结果,执行了7秒
[root@ns_10.2.1.242 test]$ time sh p3.sh 
 1 success
 2 success
 1 success
 3 success
 4 success
 2 success
 3 success
 4 success

real    0m7.007s
user    0m0.000s
sys     0m0.003s
[root@ns_10.2.1.242 test]$

另外一个 命名管道基础的文章

多进程脚本中需要注意的知识点,有3个

  1. while读取文件

         while read line 
         do
             echo $line 
         done < config.txt
  2. 管道的绑定, exec 6<>$tmp_fifofile 和 向管道写数据 echo >&6

     [root@ns_10.2.1.242 test]$ mkfifo testfifo
     [root@ns_10.2.1.242 test]$ exec  6<>testfifo 
     [root@ns_10.2.1.242 test]$ echo 1 >&6   
     [root@ns_10.2.1.242 test]$ cat testfifo 
     1
     #注意,进程会卡死的
    
     # 没有& 符号,是创建了文件名为6的文件,然后把1 输出问文件名为6的文件
     [root@ns_10.2.1.242 test]$ echo 1 >6
     [root@ns_10.2.1.242 test]$ cat 6    
     1
     [root@ns_10.2.1.242 test]$ ls -alh 6
     -rw-r--r--. 1 root root 2 Jan 22 20:26 6
  3. read -u6

     read 
         -u Read input from file descriptor fd(从文件描述符读取输入)
    
     read 读取一行,向管道写n行,就可以读取n次,n+1会堵塞
     [root@ns_10.2.1.242 test]$ mkfifo testfifo
     [root@ns_10.2.1.242 test]$ exec  6<>testfifo 
     [root@ns_10.2.1.242 test]$ echo 1 >&6   
     [root@ns_10.2.1.242 test]$ echo 1 >&6
     [root@ns_10.2.1.242 test]$ echo 1 >&6
     [root@ns_10.2.1.242 test]$ read -u6
     [root@ns_10.2.1.242 test]$ read -u6
     [root@ns_10.2.1.242 test]$ read -u6

注意:
多线程脚本应用在真实环境的时候,只需要修改CONFIG_FILEoperation函数
THREAD控制线程数量

转载于:https://www.cnblogs.com/xupeiyuan/p/shell_pipe_multi_thread.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值