shell 实现并发,并控制并发数量_shell 并发-程序员宅基地

技术标签: 并发  Experience  运维  shell  linux  多线程  管道  

为了方便理解,一步步的来
首先先看一下串行的:

#! /bin/bash

ST=$(date +%s)
for i in $(seq 1 10)
do
        echo $i
        sleep 1 # 模拟程序、命令
done

ET=$(date +%s)
TIME=$(( ${ET} - ${ST} ))
echo "time: ${TIME}"

输出结果:

1
2
3
4
5
6
7
8
9
10
time: 10

这就最原始的进程运行模拟,串行方式,无法有效利用计算机的资源,很浪费切耗时。

我们可以把进程放入后台运行,这样的可以达到并发执行的效果:

#! /bin/bash

ST=$(date +%s)
for i in $(seq 1 10)
do

  {
    
    echo $i
    sleep 1 # 模拟程序、命令
  }& # 把循环体放入后台运行,相当于是起一个独立的线程,在此处的作用就是相当于起来10个并发
done
wait # wait命令的意思是,等待(wait命令)上面的命令(放入后台的)都执行完毕了再往下执行,通常可以和&搭配使用

ET=$(date +%s)
TIME=$(( ${ET} - ${ST} ))
echo "time: ${TIME}"

执行的结果:

1
2
3
4
5
6
7
8
9
10
time: 1

有次可见,执行后时间由原来的10缩短到了1秒,这是很大的改进
但是有个问题就是,这里我的总任务才是10个,那如果我的任务是1000个,那么计算机资源就不足了,就容易造成宕机。
所以需要控制并发数据量,之前我想过很多方法,比如切割任务,和控制循环的时间等等,都不太优雅,查阅资料,找到一个可行方案:使用管道和文件描述符。

管道:
因为我对这方面也是新知识,所以一开始就看代码,有点懵,先看点理论知识。
首先说是管道,有无名管道和有名管道
无名管道,在日常使用频率超高,比如:

ps -ef | grep java
ls | wc -l

这里面的“|”就是管道,它将前一个命令的结果输出到后一个进程中,作为两个进程的数据通道,不过他是无名的。

使用mkfifo命令创建的管道即为有名管道,例如,mkfifo pipefile, pipefile即为有名管道
有名管道有一个显著的特点:
如果管道里没有数据,那么去取管道数据时,程序会阻塞住,直到管道内进入数据,然后读取才会终止这个操作,反之,管道在执行写入操作时,如果没有读取操作,同样会阻塞

由此可以得到的有用内容就是:利用有名管道的特性就可以实现一个队列的控制。

验证就不做了,网上验证资料很多。

文件描述符:
这个就不过多说了,网上资料也很多。
但是值得注意的是,文件描述符的值不能乱取,取值范围是3-(ulimit -n)-1
ulinit -n是 系统的open files
默认一般就是1024, 直接输入ulimit -n就可以查看

所以代码

#! /bin/bash

ST=$(date +%s)
[ -e /tmp/fd1 ] || mkfifo /tmp/fd1 # 创建有名管道
exec 5<>/tmp/fd1 # 创建文件描述符,以可读(<)可写(>)的方式关联管道文件,文件描述符5拥有有名管道文件的所有特性
rm -rf /tmp/fd1 # 文件描述符关联后拥有管道的所有特性,所有删除管道
NUM=$1 # 获取输入的并发数

for (( i=1;i<=${NUM};i++ ))
do
  echo >&5 # &5表示引用文件描述符5,往里面放置一个令牌
done

for i in $(seq 1 100)
do
  read -u5
  {
    
    echo $i
    sleep 1 # 模拟程序、命令
    echo >&5 # 执行完把令牌放回管道
  }& # 把循环体放入后台运行,相当于是起一个独立的线程,在此处的作用就是相当于起来10个并发
done
wait # wait命令的意思是,等待(wait命令)上面的命令(放入后台的)都执行完毕了再往下执行,通常可以和&搭配使用

ET=$(date +%s)
TIME=$(( ${ET} - ${ST} ))
echo "time: ${TIME}"

运行:

mshing@remtor:~/code$ ./Concurrent.sh 20
1
2
3
4
5
6
......
95
96
97
98
99
100
time: 5

代码分析
举个例子吧,就拿以前我们学车来说,我们学车的时候就是车少人多,假如有20人练车,但是只有5辆教练车,车钥匙放在教练那里,每个人去练车要去和教练取钥匙练完放回教练那里。那么运行就是每次只能5人同时练习,等有人把车钥匙放回教练那里,下一个才能得到钥匙去练车。只到20个人练完。任务就算完成

该并发是可用的可行的
把里面的循环范围和命令改一下就可批量并发执行了

最开始产生的需求源于自己的工作,因为工作中需要对数据库的700多张表同时truncate,然是我们的工具很不好使用,而且工具里面操作的也是串行的,有时候truncate表重建表速度更快一些,但是这样是不规范的操作,我们不应该去动表结构。所以产生了使用shell去操作数据库的想法,所以就来做个小脚本。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Magic_Ninja/article/details/119378155

智能推荐

tensorflow实现简单RNN_tensorflow rnn-程序员宅基地

文章浏览阅读586次。使用简单RNN预测谷歌的股票实验数据import numpy as npimport tensorflow.keras as kerasimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.preprocessing import MinMaxScalerdef RNN(x_train, y_train): regressor = keras.Sequential() # add the first R_tensorflow rnn

UE4调试源码正确方式_如何改变ue源码模式-程序员宅基地

文章浏览阅读7.3k次,点赞2次,收藏4次。准备1. 编译好的DevelopmentEditor或DebugEditor版本源码;2. 在对应的源码中生成的C++项目;本文以调试SoftOcclusion源码部分来看看如何执行。错误示范1.直接运行项目代码的Sln文件。2.在对应的相关源码中打上断点,点击调试执行,打开对应的包好UE4 Editor界面的项目。3.设置选项,点击“Play”运行项目,同时试图命..._如何改变ue源码模式

车载总线监控分析及仿真工具- INTEWORK VBA_vehicle bus analyser-程序员宅基地

文章浏览阅读969次。车载总线监控分析及仿真工具- INTEWORK VBA概述INTEWORK-VBA(Vehicle Bus Analyzer)车载总线监控分析及仿真工具,是由恒润自主研发的一款专业、易用的车载总线工具。具备对总线数据的监控与分析、节点仿真、报文发送、负载统计、离线回放、故障诊断、脚本仿真和Panel面板搭建等功能。当前支持CAN、CANFD、LIN、Ethernet总线类型。产品特点• 稳定可靠: 12 路高负载长时间(1 个月)监控测试不丢帧• 简单易用: 10分钟上手使用,配备详细的入门_vehicle bus analyser

JAVA反射机制及其原理实现_java反射机制原理详解-程序员宅基地

文章浏览阅读7.6k次,点赞12次,收藏47次。9.1 概念JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;public、protected、private。OO(面向对象),private私有的,不能访问。这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。**反射就是把java类中的各种成分映射成一个个的Java对象 例..._java反射机制原理详解

在线电脑内存测试软件,Everest/PC Mark内存基准测试_金士顿 8GB DDR3 1600_内存硬盘-中关村在线...-程序员宅基地

文章浏览阅读3.5k次。AIDA64(原Everest)作为一个系统检测软件,它可以详细的显示出PC每一个方面的信息。软件自带的Memory Latency评测,可以通过对内存延时的评测,直观显示出内存子系统的效能。对于普通用户来说,内存系统的快慢可以简单理解成双击文件夹的响应速度。一、原始1614MHz读:12.1GB/s 写:12.3GB/s 拷贝:11.8GB/s 延迟:47.4纳秒二、超频1696MHz读:12...._内存延迟软件

get请求中传json参数报400的错误。_get 参数传递对象400-程序员宅基地

文章浏览阅读1.5w次,点赞6次,收藏9次。需要对特殊字符进行转义后来在网上查资料找到原因了:HttpGet或 HttpPost都不能传包含 " 、“{"、"}"这样的参数,需要对特殊字符进行转义,把 " 转成%22,把 { 转成%7b,把 } 转成%7d..._get 参数传递对象400

随便推点

vue-router或者vue-admin-template中刷新跳转404的解决办法_vue admin 直接跳到404-程序员宅基地

文章浏览阅读5k次。vue或者vue-admin-template中任意页面刷新都跳转404vue在刷新的时候动态添加的router会清空,所以在动态添加的路由页面刷新的时候会因为清空的router而跳转到404.。在/src/premission.js的最下方router.afterEach修改成下面这样router.afterEach(to =>{ sessionStorage.setItem('r..._vue admin 直接跳到404

由于uvc驱动函数缺少return语句而导致内核oops的一例-程序员宅基地

文章浏览阅读282次。一、实验环境1、软件a) Vmware版本:Vmware Workstation 12.5.7b) Ubuntu版本:9.10c) 内核版本:2.6.31.14d) gcc版本:4.4.1e) gdb版本:7.02、摄像头硬件百问网自制uvc摄像头3、排查过程中,使用到的工具a) printkb) objdumpc) straced)gdb二、前言用C语言写程序时,如果定义一个带返回值的..._uvc_video_qbuf失败

Python——实例1:温度转换(Python基本语法元素及框架,代码实现)_温度转换的python程序-程序员宅基地

文章浏览阅读4.3w次,点赞64次,收藏236次。前言Python第一弹!!!Python被称为最简单好上手的语言之一,基于其极强的关联性,对各种库的引用,和资源的关联,使其实现功能非常容易。一些底层逻辑不需过多过深的理解。本篇将通过一个实例——温度转换,通过十行代码的实现,使大家对Python有最初的大体印象,并对一些基础语法和函数有初步的了解。读完本篇,你将了解到:(1)程序的格式框架(代码高亮、缩进、注释使用)(2)命名与保留字(变量、命名及33个保留字)(3)数据类型(整数、字符串、列表)(4)语句与函数(赋值语句、分支语句、函数)_温度转换的python程序

解决FeignException返回基础服务抛出的状态码-程序员宅基地

文章浏览阅读2.9w次。接上篇文章这样,虽然能够很好的处理@Valid出现的异常,但是如果是主动抛出的自定义异常和Assert断言异常,则会进入FeignException.errorStatus处理,查看源码它将message封装了feign抛出的status500以及body的content(即你主动抛出的message信息)意味着,断言异常我们可以通过ErrorDecoder的方式再通过全局异常拦截获取messag..._feignexception

openwrt 定时任务 运行shell脚本_openwrt 计划任务 运行脚本-程序员宅基地

文章浏览阅读1.8w次。步骤一:写一个xxx.sh shell脚本 【注】chmod +x xxx.sh 可执行脚本【注】环境变量 脚本的!/bin/bash下,添加如下两行: PATH=。。。(echo $PATH) export PATH 步骤二: # crontab –e这样可以已编辑模式打开个人的crontab配置文件,然_openwrt 计划任务 运行脚本

电脑——如何配置一台电脑_如何配置电脑-程序员宅基地

文章浏览阅读1.9w次,点赞109次,收藏700次。主板:显卡、电源、CPU、内存条、硬盘、显示器、鼠标、键盘、音响。_如何配置电脑

推荐文章

热门文章

相关标签