在shell脚本里批量执行程序是比较常见的方式,如果程序很多,每个执行时间比较长,则顺序执行需要花费大量的时间。

此时并发就成为我们考虑的方向。

上篇《shell多线程》中我们已经简单实现了基于for循环的并发,可以显著提高工作效率;

缺点是CPU的核心不是无限的,如果全部占用,则会影响系统的正常运行。

这个时候我们就考虑利用linux系统的管道来进行最大并发数的管控。

1.举例:

一个厕所有10个蹲位,如果100个人来使用,则势必形成竞争,这时管理员给每个蹲位一个锁和一把钥匙,先来的人拿钥匙开锁开始使用;

蹲位全部占满后后面的人等待,当有一个蹲位空出,则交出钥匙给等待队列中的第一个人,如此循环,直到等待队列为空。

2.文件描述符

管道具有存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取,这正是队列特性,解决这个问题的关键就是文件描述符了。

3. mkfifo /tmp/fd1

创建有名管道文件exec 3<>/tmp/fd1,创建文件描述符3关联管道文件,这时候3这个文件描述符就拥有了管道的所有特性,还具有一个管道不具有的特性:无限存不阻塞,无限取不阻塞,而不用关心管道内是否为空,也不用关心是否有内容写入引用文件描述符: &3可以执行n次echo >&3 往管道里放入n把钥匙

4.完整代码

#!/bin/bash

[ -e /tmp/fd1 ] || mkfifo /tmp/fd1 #创建有名管道
exec <>/tmp/fd1 #创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性
rm -rf /tmp/fd1 #关联后的文件描述符拥有管道文件的所有特性,所以这时管道文件可以删除,我们留下文件描述符来用就可以
for ((i=;i<=;i++))
do
echo >& #&3代表引用文件描述符3,这条命令代表往管道里面放入了一个"令牌",文件描述符可以使用0/1/2/225之外的其他数字,这几个已被占用
done for ((i=;i<=;i++))
do
read -u3 #代表从管道中读取一个令牌
{
sleep #sleep 1用来模仿执行一条命令需要花费的时间(可以用真实命令来代替)
echo 'success'$i
echo >& #代表我这一次命令执行到最后,把令牌放回管道
}&
done
wait exec <&- #关闭文件描述符的读
exec >&- #关闭文件描述符的写

4.由于从前写的脚本大部分都是以方法的形式存在的,所以想要落地就需要对上面的脚本做一些修改,保证每次循环都会执行一个方法

t1Fun(){
echo
}
t2Fun(){
echo
}
t3Fun(){
echo
}
t4Fun(){
echo
}
[ -e /tmp/fd1 ] || mkfifo /tmp/fd1
exec <>/tmp/fd1
rm -rf /tmp/fd1
for ((i=;i<;i++))
do
echo >&
done for ((i=;i<=;i++))
do
read -u3
{
sleep
if [ $i -eq ];then
t1Fun
elif [ $i -eq ];then
t2Fun
elif [ $i -eq ];then
t3Fun
else
t4Fun
fi
echo >&
}&
done
wait exec <&-
exec >&-

shell多线程(2)之基于管道实现并发的更多相关文章

  1. [shell进阶]——shell多线程

    关于shell的多线程 1. 多线程并发执行任务,而不用一台台的串行执行,能更快更高效 2. Shell并没有多线程的概念,所以: * 一般使用wait.read等命令技巧性地模拟多线程实 * 使用命 ...

  2. 模拟ssh远程执行命令,粘包问题,基于socketserver实现并发的socket

    06.27自我总结 1.模拟ssh远程执行命令 利用套接字编来进行远程执行命令 服务端 from socket import * import subprocess server = socket(A ...

  3. 再谈AbstractQueuedSynchronizer:基于AbstractQueuedSynchronizer的并发类实现

    公平模式ReentrantLock实现原理 前面的文章研究了AbstractQueuedSynchronizer的独占锁和共享锁,有了前两篇文章的基础,就可以乘胜追击,看一下基于AbstractQue ...

  4. 再谈AbstractQueuedSynchronizer3:基于AbstractQueuedSynchronizer的并发类实现

    公平模式ReentrantLock实现原理 前面的文章研究了AbstractQueuedSynchronizer的独占锁和共享锁,有了前两篇文章的基础,就可以乘胜追击,看一下基于AbstractQue ...

  5. Java 并发编程-再谈 AbstractQueuedSynchronizer 3 :基于 AbstractQueuedSynchronizer 的并发类实现

    公平模式ReentrantLock实现原理 前面的文章研究了AbstractQueuedSynchronizer的独占锁和共享锁,有了前两篇文章的基础,就可以乘胜追击,看一下基于AbstractQue ...

  6. Monad、Actor与并发编程--基于线程与基于事件的并发编程之争

    将线程.事件.状态等包装成流的源. 核心:解决线程的消耗和锁的效率问题. Java和Node.js可以说分别是基于线程和基于事件的两个并发编程代表,它们互相指责瞧不起对方,让我们看看各种阵营的声音: ...

  7. 基于socketserver实现并发

    基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环 socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题) 一.分析socketserv ...

  8. scrapy框架基于管道的持久化存储

    scrapy框架的使用 基于管道的持久化存储的编码流程 在爬虫文件中数据解析 将解析到的数据封装到一个叫做Item类型的对象 将item类型的对象提交给管道 管道负责调用process_item的方法 ...

  9. shell多线程,wait

    文章来源,wait的使用效果还是不错的 最近在使用shell做一些部署工作,在使用过程中,效率一直不高.想提高效率,经过分析发现,并不是所有操作都是需要串行的,一些操作是可以进行并行操作的.经过学习, ...

随机推荐

  1. JavaScript window.location物

    演示样例 注意 方法 常常使用window.location.它的结构总是记不住.简单梳理下.方便以后查询. 演示样例 URL:http://b.a.com:88/index.php? name=ka ...

  2. WPF多线程UI更新

    前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对象.)这是很常见的一个错误,一不小 ...

  3. uva 11552 Fewest Flops 线性dp

    // uva 11552 Fewest Flops // // 二维线性dp // // 首先,在该块必须是相同的来信.首先记录每块有很多种书 // 称为是counts[i]; // // 订购f[i ...

  4. 最近更新电脑管家开机速度约慢很多木有?$计算机管理-废话$.qmgc

    最近更新电脑管家开机速度约慢很多木有? 一旦开机速度是几十秒,由于前几天更新电脑管家,大约几十秒钟成为一个点开机时间! 同样在一个多垃圾清理桌面图标! 右键菜单也看不到属性 须要到下面位置查看: wa ...

  5. uwp - 控件精确移动动画

    原文:uwp - 控件精确移动动画 先看效果图: 一共有8个GRID,黄色的负责移动,其他7个负责定位.新建一个页面page,替换默认代码: <UserControl.Resources> ...

  6. ArcGIS API for Silverlight 学习笔记

    这里主要讲解展示不同的服务地图 先看一个实例: 新建一个Silverlight项目,在MainPage.xaml文件中,引入 ESRI.ArcGIS.Client 命名空间和 ESRI.ArcGIS. ...

  7. C++ Primer 学习笔记_104_特殊工具与技术 --嵌套类

    特殊工具与技术 --嵌套类 能够在还有一个类内部(与后面所讲述的局部类不同,嵌套类是在类内部)定义一个类,这种类是嵌套类,也称为嵌套类型.嵌套类最经常使用于定义运行类. 嵌套类是独立的类,基本上与它们 ...

  8. 【 D3.js 入门系列 --- 6 】 如何使移动图表

    我的个人博客是: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. [5.1]节中制作了一个比較完好的图表.但它是静态的.想做出它的动 ...

  9. xmpp和OpenFire示例,即时聊天室,支持离线消息

    让我说说为什么写这个博客,这是因为我在上周末的研究XMPP和OpenFire,从互联网上下载Demo,但跑不起来.它花了很长的时间.它被改造.抬高.篇博文也是希望后边学习XMPP和OpenFire的同 ...

  10. Qt父窗口设置为桌面

    #include "widget.h"#include <QApplication>#include"windows.h"int main(int ...