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控制线程数量

shell 中用管道模拟多线程的更多相关文章

  1. shell模拟“多线程”

      shell中并没有真正意义上的多线程,要实现"多线程"可以启动多个子进程,并将子进程放入后台执行来模拟多线程,最大程度利用CPU性能. 循环中执行并行代码 #!/bin/bas ...

  2. Linux下模拟多线程的并发并发shell脚本

    分享一个在Linux下模拟多线程的并发脚本,使用这个脚本可以同时批量在定义数量的服务器上执行相关命令,比起普通for/while循环只能顺序一条一条执行的效率高非常多,在管理大批服务器时非常的实用.  ...

  3. php模拟多线程

    一:应该知道的: php本身是不支持多线, 但是php的好搭档,apache和linux是支持的,故lamp才是最佳组合,还在使用win服务器的现在知道为什么要用linux吧.既然是模拟的, 就不是真 ...

  4. php使用curl模拟多线程发送请求

    每个PHP文件的执行是单线程的,但是php本身也可以用一些别的技术实现多线程并发比如用php-fpm进程,这里用curl模拟多线程发送请求.php的curl多线程是通过不断调用curl_multi_e ...

  5. 利用curl 模拟多线程

    所谓多线程就是多个 程序同时运行,单线程:执行一段逻辑,等待完成后 在执行另外一个. 多线程:几个逻辑同时进行处理,不需要相互等待,提高了总的执行时间 接下来就用curl实现多线程 实现逻辑 1. f ...

  6. 通过curl模拟多线程抓取网页(curl_multi_*)

    curl请求多个url,以前都是使用循环来处理.最近发现可以通过curl_multi_*系列函数来模拟多线程.比对一下,发现如果请求的url只有几个,2种方案耗时差不多,但是url比较多,差距就非常明 ...

  7. Linux Shell中管道的原理及C实现框架

    在shell中我们经常用到管道,有没考虑过Shell是怎么实现管道的呢? cat minicom.log | grep "error" 标准输入.标准输出与管道 我们知道,每一个进 ...

  8. C# WPF 中用代码模拟鼠标和键盘的操作

    原文:C# WPF 中用代码模拟鼠标和键盘的操作 原文地址 C#开发者都知道,在Winform开发中,SendKeys类提供的方法是很实用的.但是可惜的是,在WPF中不能使用这个方法了. 我们知道,在 ...

  9. 【JavaScript】吃饱了撑的系列之JavaScript模拟多线程并发

    前言 最近,明学是一个火热的话题,而我,却也想当那么一回明学家,那就是,把JavaScript和多线程并发这两个八竿子打不找的东西,给硬凑了起来,还写了一个并发库concurrent-thread-j ...

随机推荐

  1. linux根据该文件夹的读取权限和权限运行差异

    假设你linux下使用ls.细心的你会发现居然夹有权限运行.例如: drwxrwxr-x 11 cl cl 4096  9 25 14:22 ./ drwxr-xr-x 49 cl cl 4096 1 ...

  2. 自定义错误页面mvc用法

    原谅我这个新手,对大神们来说这么简单的问题,竟折腾了我一个上午,仅此文章做个记录,供以后备用. 自定义错误页面(custom error pages)在asp.net webform里的配置请看htt ...

  3. 《Java程序猿面试笔试宝典》之Java与C/C++有什么异同

    Java与C++都是面向对象语言,都使用了面向对象思想(比如封装.继承.多态等),因为面向对象有很多非常好的特性(继承.组合等),使得二者都有非常好的可重用性. 须要注意的是,二者并不是全然一样,以下 ...

  4. maven snapshot和release版本号之间的差

    在使用maven过程.我们经常会在不稳定的状态有很多公共图书馆在发展阶段.需要改变在任何时间和公布,你可能有一天一次发布.经验bug时间,甚至一天公布N次要.我们知道,.maven依赖管理是基于管理的 ...

  5. JDK5什么是新的线程锁技术(两)

    一个. Lock线程同步实现互斥 Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也是一个对象. 两个线程运行的代码片段要实现同步相互排斥的效果.他们必须用 ...

  6. [LeetCode53]Maximum Subarray

    问题: Find the contiguous subarray within an array (containing at least one number) which has the larg ...

  7. 2015-12-1 Visual Studio 2015 Update 1发布

    http://news.cnblogs.com/n/533856/ 下载地址 文件名 cn_visual_studio_enterprise_2015_with_update_1_x86_x64_dv ...

  8. Java 打开文件的两种方式

    import java.awt.Desktop; import java.io.File; import java.io.IOException; public class LnkDemo { pub ...

  9. HDU 4686 Arc of Dream(递归矩阵加速)

    标题效果:你就是给你一程了两个递推公式公式,第一个让你找到n结果项目. 注意需要占用该公式的复发和再构造矩阵. Arc of Dream Time Limit: 2000/2000 MS (Java/ ...

  10. 解决:对 PInvoke 函数的调用导致堆栈不对称问题

    解决:对 PInvoke 函数的调用导致堆栈不对称问题 问题描述: 在使用托管代码调用非托管代码时,发生“对 PInvoke 函数“UseTwiHikVisionDllTest!UseTwiHikVi ...