zoukankan      html  css  js  c++  java
  • 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控制线程数量

  • 相关阅读:
    二叉树的最大距离
    MS CRM 2011 RibbonExport Utility下载以及实用说明
    MS CRM 2011中的解决方案——使用
    MS CRM 2011的自定义与开发(5)——关系编辑器
    MS CRM 2011 RC中的新特性(5)——定期约会
    MS CRM2011中的事件脚本——入门
    MS CRM 2011 汇总更新 3
    MS CRM 4中模拟PartyList字段的方法
    MS CRM 2011的自定义与开发(4)——属性编辑器
    MS CRM 2011中的解决方案Solution_简介
  • 原文地址:https://www.cnblogs.com/xupeiyuan/p/shell_pipe_multi_thread.html
Copyright © 2011-2022 走看看