【shell】限制任务并发

shell - 限制任务并发

遇到问题

数千个任务同时执行会导致服务器资源不足, 处理速度越来越慢直到夯住、崩溃

如何解决

通过限制任务最大并发数来解决, 下面提供两种方式, 假设循环 sh aaa.sh

  1. 通过 ps -ef | grep aaa.sh 获取当前任务并发数, 来判断并决定下一步操作

优点是简单方便快速; 缺点是限制并发数不够精确 (会出现同一时间超过10个任务执行的情况)

while true
do
  count=`ps -ef | grep aaa.sh | wc -l`
  if [ $count -lt 10 ];then
    sh aaa.sh
  else
   # 并行度 >= 10, 等待后进入下一次循环判断
    sleep 30
  fi
done
  1. 利用命名管道读操作的阻塞性来限制最大并发数

优点是精确控制并发数; 缺点是稍微麻烦难理解一点 (管道、文件描述符)

# 创建命名管道、关联文件描述符、删除命名管道
mkfifo /tmp/f6
exec 6<>/tmp/f6
rm -rf /tmp/f6

# 最大并发 10
concurrency=10
for ((i=1;i<=${concurrency};i++));do
  echo >&6
done

while true
do
  # 读取: 如缓冲区不为空, 锁定一个并发量, 后台执行一个任务;
  # 如缓冲区为空则读取发生阻塞, 直到已启动的任务执行完成并释放一个并发量
  read -u6
  {
    sh aaa.sh
    # 写入: 任务执行完成, 释放一个并发量
    echo >&6
  } &
done

wait
# 关闭文件描述符的读和写
exec 6<&-
exec 6>&-

知识点

管道中, 数据通过内核缓冲区进行传输:
当一个进程向管道中写入数据时, 如果缓冲区已满, 则写入操作会被阻塞, 直到另一个进程从管道中读取数据为止
当一个进程从管道中读取数据时, 如果缓冲区为空, 则读取操作会被阻塞, 直到另一个进程向管道中写入数据为止

  • mkfifo /tmp/f6 : 创建一个名为 /tmp/f6 的 FIFO 文件, 也称为命名管道
    • 多个进程可以同时打开同一个命名管道进行读写操作
    • 读一个少一个, 从管道中读取数据后, 缓冲区的数据将被删除
  • exec 6<>/tmp/f6 文件描述符与命名管道关联
    • 文件描述符 6 与命名管道关联后, 可以通过 6 来对管道进行读写
  • rm -rf /tmp/f6 : 删除命名管道
    • 注意: 删除该 FIFO 文件并不会影响已经打开该文件的进程, 因此仍可以使用文件描述符 6 进行读写操作
  • { }& 将一个或一组命令放入后台运行, 以便继续执行其他命令
  • wait 等待上面命令全部执行完成后, 再执行下面的命令
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值