shell实现多并发控制

news2024/12/25 12:49:46

背景:

遇到一个业务需求,一个上位机需要向多个下位机传送文件,当前的实现是for循环遍历所有下位机,传送文件,但是此种方法耗时太久,需要优化。因此可以通过并发的方式向下位机传送文件。

这边写一段测试代码,就简单输出一些内容。(输出1-10数字)

注意:以下每个点都是依次递进的。

实现过程:

1. 通过串行的方式实现

遍历1-10,然后将其输出(中间每个操作休眠1s,最终耗时10s)

# 串行执行命令
echo -e "串行执行:"
all_num=10
a=$(date +%H%M%S)

for ((i=1;i<=${all_num};i++))
do
{
	sleep 1
	echo ${i}
}
done

b=$(date +%H%M%S)
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"

结果:

 当前问题:

输出1-10,是10个循环,是按照顺序执行的,每一个循环1s,那么10个循环是10s,那如果需要输出1-1000呢?就是需要1000s,效率过于低下,所以需要并发执行。

2. 使用&,以及wait并发执行

知识储备:

符号&:在命令的末尾加上&,表示该命令在后台执行,后面的命令就无需等待这条命令执行完就可以执行。

wait:将wait之前的命令都执行结束(当前进程下的子进程都执行结束),才开始wait之后后面的语句。

代码:(耗时1s)

# 2.并发执行(&符号表示{}内的命令将在后台执行,后面的命令不用等前面的命令执行完就可以执行了)
# (wait是将当前脚本进行下的子进程都执行结束,然后在执行后面的语句)

echo -e "并发执行:"
all_num=10
a=$(date +%H%M%S)

for ((i=1;i<=${all_num};i++))
do
{
	sleep 1
	echo ${i}
}&
done

wait

b=$(date +%H%M%S)
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"

结果:

由此可以发现,并发执行确实在时间上优化了很多,但是有需要考虑一个问题:如果现在有1000个任务,那么后台就需要并发1000个任务(一下创建出1000个子进程),这样对系统造成非常大的压力,并发任务数量增多,操作系统的处理速度就会变慢,甚至出现其他不稳定因素。所以,最好是可以控制并发数(控制子进程的数量)。

3. 使用文件描述符和管道控制并发数

知识储备:

管道特性:管道默认是阻塞的,当进程从管道中读取数据,如果没有数据则进程会阻塞;

                当一个进程往管道中不断地写入数据但是没有进程去读取数据,此时只要管道没有满是可以写的,但若管道放满数据的则会报错。

有名管道:它是一种文件类型,在文件系统中可以看到。

利用有名管道的上述特性就可以实现一个队列控制了。

你可以这样想:一个公共厕所总共就10个蹲位,这个蹲位就是队列长度,厕所门口放着10把钥匙,要想上厕所必须拿一把药匙,上完厕所后归还药匙,下一个人就可以拿药匙进去上厕所了,这样同时来了1000个人上厕所,那前十个人抢到药匙进去上厕所了,后面的990人需要等一个人出来归还药匙才可以拿到药匙进去上厕所,这样10把药匙就实现了控制1000人上厕所的任务(os中称之为信号量)。

管道具有存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取,这正是队列特性,但是问题是当往管道文件里面放入一段内容,没人取则会阻塞,这样你永远也没办法往管道里面同时放入10段内容(想成10把药匙),解决这个问题的关键就是文件描述符了。

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

 代码:

# 3.并发执行(&符号表示{}内的命令将在后台执行,后面的命令不用等前面的命令执行完就可以执行了)
# 控制并发数量(根据自己的当前业务需求)

echo -e "并发执行(控制并发数量,利用管道,文件描述符):"
all_num=10
# 并发的进程数
thread_num=5
a=$(date +%H%M%S)

# mkfifo 创建有名管道
myfifo="fd1"
mkfifo=${myfifo}

# 创建文件描述符,以可读(<)和可写(>)的方式关联管道文件,这时候文件描述符2就有了有名管道文件的所有特性
# 关联之后的文件描述符拥有管道文件的所有特性,所以可以将管道文件进行删除,之后使用文件描述符2即可
exec 2<>${myfifo}
rm -f ${myfifo}

# 为文件描述符创建占位信息(&2表述文件描述符2,往管道里面放入了一个“令牌”,相当于最多可以开启有thread_num个进程)
for ((i=1;i<=${thread_num};i++))
do
{
  echo >&2
}
done

# 命令
for ((i=1;i<=${all_num};i++))
do
# 代表从管道中获取一个令牌(一共有thread_num个进程,现在使用一个进程,2是代表文件描述符)
read -u2
{
	sleep 1
	echo ${i}
    # 代表执行完当前命令,将这个令牌又放入到管道中(使用完这个进程,将这个进程又返还回去)
    echo >&2 
}&
done

wait

# 命令执行完成,关闭文件描述符的读写
exec 2<&-
exec 2>&-
b=$(date +%H%M%S)
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"

结果:

这种方法没有第二种方法快,但是比方法一块,这样是既可以提高效率,又实现了并发控制。

4. 使用xargs -P控制并发数

知识储备:

-I:执行多条命令(具体使用请查下,这里只是简单普及) -I后面的{},输出是sh -c中的内容,它代表seq 1 ${all_num},即1-10

-n:指定每行字符数

-P:表示支持的最大进程数,默认为1。为0时表示尽可能地大

代码:

# 4.并发执行(使用xargs -P控制并发数)

all_num=10
thread_num=5
 
a=$(date +%H%M%S)

# cp -rf /root/result /root/test-patch/ | xargs -n 1 -I {} -P ${thread_num} sh -c
seq 1 ${all_num} | xargs -n 1 -I {} -P ${thread_num} sh -c "sleep 1;echo {}"
 
b=$(date +%H%M%S)
 
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"

结果:

5.  使用parallel控制并发数

 知识储备:

-j 是控制并发数(command1 ::: arg1 arg2 arg3)。

并行执行command1命令,并使用:::符号传递arg1、arg2和arg3参数。

代码:

# 5.并发执行(使用parallel控制并发数)
all_num=10
thread_num=6
 
a=$(date +%H%M%S)
 
parallel -j 5 "sleep 1;echo {}" ::: `seq 1 10`
 
b=$(date +%H%M%S)
 
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"

结果:因为当前电脑没有安装parallel ,就不贴结果了。

参考:shell队列实现线程并发控制_shell并发执行命令_宗而研之的博客-CSDN博客

【Linux】shell脚本实现多并发_shell 多线程并发执行_zclinux_的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/643012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue3 第二十七章】路由和状态管理

一、路由 1.1 服务端路由 与 客户端路由 服务端路由 服务端路由指的是服务器根据用户访问的 URL 路径返回不同的响应结果。当我们在一个传统的服务端渲染的 web 应用中点击一个链接时&#xff0c;浏览器会从服务端获得全新的 HTML&#xff0c;然后重新加载整个页面。客户端路…

人机交互学习-2 人机交互基础知识

人机交互基础知识 交互框架作用执行/评估活动周期 EEC四个组成部分七个阶段和两个步骤 执行隔阂&评估隔阂扩展EEC模型四个部分两个阶段 交互形式命令行交互菜单驱动界面基于表格的界面直接操纵问答界面隐喻界面自然语言交互交互形式小结 理解用户信息处理模型信号处理机人类…

“秩序与自由”——超详细的低代码开发B端产品前端页面设计规范

Hi&#xff0c;我们是钟茂林和李星潮&#xff0c;来自万应低代码 UI 设计团队。 编辑搜图 编辑搜图 左&#xff1a;钟茂林 右&#xff1a;李星潮 在过去&#xff0c;B 端应用通常只在企业内部员工中使用&#xff0c;与 C 端产品数以千万计的用户相比显得少之…

Pycharm 配置Django 框架(详解篇)

首先你必须具备pycharm 专业版 / 社区版也可以 打开pycharm专业版 找到在最下方菜单栏找到 Terminal 第二步&#xff1a;检查自己的python版本 python --version 第三步&#xff1a; 寻找和自己python版本匹配的django版本 &#xff08;图片来源&#xff1a; 化雨随风 …

【NLP模型】文本建模(2)TF-IDF关键词提取原理

一、说明 tf-idf是个可以提取文章关键词的模型&#xff1b;他是基于词频&#xff0c;以及词的权重综合因素考虑的词价值刻度模型。一般地开发NLP将包含三个层次单元&#xff1a;最大数据单元是语料库、语料库中有若干文章、文章中有若干词语。这样从词频上说&#xff0c;就有词…

华为OD机试真题 JavaScript 实现【最小传输时延】【2023 B卷 100分】,附详细解题思路

一、题目描述 某通信网络中有N个网络节点&#xff0c;用1到N进行标识。 网络通过一个有向无环图表示&#xff0c;其中图的边的值表示结点之间的消息传递时延。 现给定相连节点之间的时延列表times[i] {u,v,w}&#xff0c;u表示源节点&#xff0c;v表示目的节点&#xff0c;…

C++入门攻略

C补足C语言部分缺陷 1.命名空间&#xff1a;1.1 命名空间namespace关键字1.命名空间中可以定义变量、函数、类型2.命名空间可以嵌套3.相同命名空间共存 1.2 命名空间的使用方式&#xff1a;1.名称加用域作用限定符的方式访问&#xff08;同上&#xff09;2.使用using引入某个空…

现在学大数据还来得及么

种一棵树最好的时机是十年前&#xff0c;其次是现在。如果你想学&#xff0c;那么就一定来的及。 Python 已成利器 在大数据领域中大放异彩 Python&#xff0c;成为职场人追求效率的利器&#xff0c;因为不管什么工作&#xff0c;数据都会是工作的一部分&#xff0c;有数据的…

学习【菜鸟教程】【C++ 继承】

链接 1. 教程原文 面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类&#xff0c;这使得创建和维护一个应用程序变得更容易。这样做&#xff0c;也达到了重用代码功能和提高执行效率的效果。 当创建一个类时&#xff0c;您不需要重新编写新的…

精通postman教程(一)下载及安装详解

作为一名测试工程师&#xff0c;那么Postman绝对是大伙必备的工具之一。 在这个系列教程中&#xff0c;我将为大伙详细讲解如何使用Postman进行API测试。 今天我将先为大伙介绍Postman的下载安装方法&#xff0c;让你们快速上手这款工具。 一、下载 下载地址&#xff1a;Do…

基于Java学院党员管理系统设计与实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

Java学习笔记(视频:韩顺平老师)4.0

如果你喜欢这篇文章的话&#xff0c;请给作者点赞哟&#xff0c;你的支持是我不断前进的动力。 因为作者能力水平有限&#xff0c;欢迎各位大佬指导。 目录 如果你喜欢这篇文章的话&#xff0c;请给作者点赞哟&#xff0c;你的支持是我不断前进的动力。 控制结构 顺序 分…

【面试系列】2023金三银四面经

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;2022年度博客之星前端领域TOP 2&#xff0c;前端领域优质作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步…

深入浅出RTA广告投放

一、RTA诞生背景 广告主在媒体投放广告时&#xff0c;往往需要将数据回传给DSP或媒体平台&#xff0c;供他们进行针对性优化。但是随着很多公司对数据隐私性的重视和保护&#xff0c;导致广告主不能或者不愿意将数据回传给DSP或媒体平台&#xff0c;但这样做又必然导致投放模型…

Lightroom Classic 2023(版本 12.3)主要新增功能

macw发布了Adobe Lightroom Classic 2023(版本 12.3)软件&#xff0c;该版本新增了哪些功能呢&#xff1f;随着小编一起了解一下吧&#xff01; 主要新增功能概述 轻松消除图像中的杂色 借助 AI 支持的降噪功能&#xff0c;可以轻松、有效地消除 RAW 图像中的杂色&#xff0c…

抽象工厂模式(六)

过气的&#xff0c;终究是过气了 上一章简单介绍了工厂方法模式(五), 如果没有看过,请观看上一章 一. 抽象工厂模式 引用 菜鸟教程里面的单例模式介绍: https://www.runoob.com/design-pattern/abstract-factory-pattern.html 抽象工厂模式&#xff08;Abstract Factory Pat…

记Gitlab备份与设置自动备份

今天给Gitlab做了一个备份&#xff0c;并且设置了每天自动备份&#xff0c;记录一下。 一、导出全部项目 由于Gitlab Web页面并没有自动备份的相关设置&#xff0c;只有各个项目有一个“导出项目”功能。为了保证安全&#xff0c;先把所有项目全部使用“导出项目”功能导出一…

Redis实战案例1-短信登录

Redis的共享session应用 1. 项目的相关工作 导入sql文件 找到对应的sql文件即可 基本表的信息 基本架构 导入对应的项目文件&#xff0c;启动相关的service服务; 在nginx-1.18.0目录下启动命令行start nginx.exe&#xff1b; 2. 基于session实现登录的流程 这里利用到Javaweb中…

脚踩Midjourney、Stable Diffusion,谷歌StyleDrop真要杀疯了!

脚踩Midjourney、Stable Diffusion&#xff0c;谷歌StyleDrop真要杀疯了 导语StyleDrop组件MuseMuse架构Muse图像生成实现流程 适配器微调Adapter TuningMuse中的Adapter Tuning 反馈迭代训练 最近&#xff0c;谷歌发布了一款引人瞩目的AI绘画工具——StyleDrop。这个工具通过学…

ZYNQ - 以太网远程更新贴片SD卡应用程序【SD NAND应用】

写在前面 对于ZYNQ系列的板卡固化&#xff0c;可以通过JTAG接口&#xff0c;使用SDK固化到FLASH中&#xff0c;或者可将SD卡取出将SD卡中保存的固化工程进行修改&#xff0c;但在很多情况下&#xff0c;离线更新会很不方便&#xff0c;本文借鉴网上常见的远程更新QSPI FLASH的…