shell中并没有真正意义上的多线程,要实现“多线程”可以启动多个子进程,并将子进程放入后台执行来模拟多线程,最大程度利用CPU性能。

循环中执行并行代码

#!/bin/bash
date
for i in `seq 1 5`
do
{
echo "sleep 5"
sleep 5
} &
done
wait
date

执行结果如下:

Thu Oct 19 19:58:43 CST 2017 sleep 5 sleep 5 sleep 5 sleep 5 sleep 5 Thu Oct 19 19:58:48 CST 2017

由此我们可以看出,所有的for循环下的指令都可以同时执行,使用wait命令等待所有子进程结束。

  这样能够提供脚本运行的效率,但是我们又不能无限制的让这个for循环去启动子进程,所以就需要我们对这个进程数进行设置。

#!/bin/bash
date
trap "exec 5>&-; exec 5 <&-; exit 0" 2
THREAD_NUM=10
tmp_fifofile="/tmp/$$.fifo"
mkfifo "$tmp_fifofile"
exec 5<>"$tmp_fifofile"
rm $tmp_fifofile
for ((i=0;i<$THREAD_NUM;i++));do
echo
done >&5 for i in `seq 1 50`
do
read -u5
{
sleep 1
echo "----------"
echo >&5
} &
done
wait
exec 5>&-
date

trap "exec 5>&-; exec 5 <&-; exit 0" 2#接收信号2(Ctrl +C )的操作,并关闭描述符5

THREAD_NUM=10#允许的最大进程数。

tmp_fifofile="/tmp/$$.fifo"#以脚本运行的当前进程ID号作为文件名。

mkfifo "$tmp_fifofile"#新建一个随机FIFO管道文件。

exec 5<>"$tmp_fifofile"#定义文件描述符5指向这个FIFO管道文件(对文件描述符5的所有操作等同于对管道文件)。

rm $tmp_fifofile#删除管道文件,删除与否都无所谓。

    echo
done >&5```#使用一个for循环向管道中输入$THREAD_NUM个空行;>符号为输出重定向;&符号表示5为文件描述符,也就是说&5表示文件描述符5。
`read -u5`#表示从文件描述符5(管道)中读取行,每次读一行,如果读完了就会挂起,直到管道中再次有可读的行。
`echo >&5`#再次向管道中写入空行,避免挂起的for循环停止执行。
`} &`#将进程放到后台,表明for循环中的`sleep 1`与`----------`这两条指令有10个进程在后台同时执行
`wait`等待所有进程执行完成
`exec 5>&-`#删除文件描述符5 ### 关联详解
#### Linux文件描述符
&nbsp; 文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。
&nbsp; 每个Unix进程(除了可能的守护进程)应均有三个标准的POSIX文件描述符,对应于三个标准流:
| 整数值 | 名称 | <unistd.h>符号常量 | <stdio.h>文件流 |
|----|----|----|----|
|0|Standard input|STDIN_FILENO|stdin
|1|Standard output|STDOUT_FILENO|stdout
|2|Standard error|STDERR_FILENO|stderr
&nbsp; 我们可以使用exec指令自行定义、绑定文件描述符,文件描述符一般从3~(n-1)可以使用,n=ulimit -n的数值。
#### 管道
&nbsp; Linux管道包含两种
- 匿名管道
- 命名管道 &nbsp; 管道有一个特点,如果管道中没有数据,那么取管道数据的操作就会滞留,直到管道内进入数据,然后读出后才会终止这一操作;同理,写入管道的操作如果没有读取管道的操作,这一动作就会滞留。
##### 匿名管道
&nbsp; 在Unix或类Unix操作系统的命令行中,匿名管道使用ASCII中垂直线|作为匿名管道符,匿名管道的两端是两个普通的,匿名的,打开的文件描述符:一个只读端和一个只写端,这就让其它进程无法连接到该匿名管道。
##### 命名管道
&nbsp; 命名管道也称FIFO,从语义上来讲,FIFO其实与匿名管道类似,但值得注意:
- 在文件系统中,FIFO拥有名称,并且是以设备特俗文件的形式存在的;
- 任何进程都可以通过FIFO共享数据;
- 除非FIFO两端同时有读与写的进程,否则FIFO的数据流通将会阻塞;
- 匿名管道是由shell自动创建的,存在于内核中;而FIFO则是由程序创建的(比如mkfifo命令),存在于文件系统中。

shell模拟“多线程”的更多相关文章

  1. Linux shell模拟多线程拷贝

    #!/bin/sh #日志文件 log_file=/data/threadcp.log a=$(date +%H%M%S) echo -e "startTime:\t$a" #最大 ...

  2. shell 中用管道模拟多线程

    shell 中用管道模拟多线程 这里以两个例子来对比多线程和单进程 单线程的例子 # config.txt在这个例子和多线程的例子中都会用到 [root@ns_10.2.1.242 test]$ ca ...

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

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

  4. php模拟多线程

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

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

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

  6. adb shell模拟点击事件(input tap)

    前言:appium定位也不是万能的,有些元素还是定位不到,这个时候只能换一个方式定位了,可以使用这个adb shell模拟点击. 1.input可以实现的功能 输入文本信息:input text gu ...

  7. 利用curl 模拟多线程

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

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

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

  9. PHP+shell实现多线程的方法

    PHP+shell实现多线程的方法 这里介绍怎样借助shell脚本实现多线程. 先写个简单的php代码.这里为了让脚本运行时间更长.方便看效果,sleep一下.呵呵.先看下test.php的代码:ls ...

随机推荐

  1. 在winsshd 中添加id_rsa.pub 实现Windows 服务器主机自动信任Linux 客户端

    文章一. 生成密钥: 在Linux主机(ssh客户端),通过ssh-keygen在建立SSH keys# ssh-keygen -t rsa (连续三次回车,即在本地生成了公钥和私钥,不设置密码)将在 ...

  2. Ubuntu --- not enough free disk space

    Ubuntu系统更新时出现not enough free disk space. 原因是系统的就内核占满了/boot 的空间,只要将旧内核删除就ok了 首先,命令 uname -r  查看当前内核,( ...

  3. C# 类初始化顺序

    C#的类初始化顺序和Java以及C++类初始化顺序是不同的,曾经我被这个问题害惨了.对于C#和Java,其共同点都是先变量后构造函数,先静态后普通 区别在于,C#是子类变量->父类变量-> ...

  4. vue-cli启动本地服务,局域网下通过ip访问不到的原因

    1.问题描述: 新开发了一个vue-cli项目,想通过手机查看效果,发现访问不到,ip地址和端口号都没错但是手机访问不到,在本机电脑浏览器输入ip端口号一样访问不到,只能通过localhost:808 ...

  5. 配置springMVC

    1.web.xml 前端控制器 配置规则:*.do: 拦截请求路径所有的后缀为.do;/* : 拦截所有, .jsp页面也会拦截; 不会使用此配置, 因为视图会无法跳转;/ : 拦截所有, .jsp页 ...

  6. UI交互设计教程分享:提高界面交互体验的“葵花宝典”

    ​本次分享的是在界面设计中最长实用也最容易被忽略的十个原则,就是尼尔森十大可用性设计原则,这是十分基础且重要的原则.原则是死的,如何正确的结合到实际运用中才是关键.接下来我会通过对每一个原则的理解和现 ...

  7. Netty 零拷贝(一)NIO 对零拷贝的支持

    Netty 零拷贝(二)NIO 对零拷贝的支持 Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html) 非直接缓冲区(HeapBy ...

  8. 让IIS 7 如同IIS 8 第一次请求不变慢

    当我们把网站部署在IIS7或IIS6S的时候,每当IIS或是Application Pool重启后,第一次请求网站反应总是很慢,原因大家都知道(不知道可以参考这个动画说明ASP.NET网页第一个Req ...

  9. jsoup Java HTML解析器:使用选择器语法来查找元素

    jsoup Java HTML解析器:使用选择器语法来查找元素 使用选择器语法来查找元素 问题 你想使用类似于CSS或jQuery的语法来查找和操作元素. 方法 可以使用Element.select( ...

  10. 2018.09.19 atcoder AtCoDeer and Rock-Paper(贪心)

    传送门 sb贪心啊. 显然能选帕子就选帕子. 首先假设第一个人全出石头. 考虑把一些石头修改成帕子. 这样贡献只增不减,加起来就是答案. 代码: #include<bits/stdc++.h&g ...