linux shell多进程

最近看了一些博客研究怎么把单进程的shell脚本改成多进程提升效率,大多数写的都不尽如人意,决定自己写一个

首先看单进程脚本

#!/bin/bash

function task {
    arg=${1}
    echo "执行任务: ${arg}"
    # 假设每个任务平均耗时2s
    sleep 2s
}

# 一共发布20个任务
for ((i=0; i<20; i++)) do
    task ${i}
done

单进程顺序执行需要耗费40s

 

再看多进程版本

#!/bin/bash

function task {
    arg=${1}
    echo "执行任务: ${arg}"
    # 假设每个任务平均耗时2s
    sleep 2s
}

# 创建队列和锁
mkfifo list
mkfifo lock
# 插入多个数据不阻塞
exec 3<>list
exec 4<>lock

# 主进程发布任务到队列
for i in {1..20}; do
    echo ${i} >&3
done
# 释放锁
echo >&4

# 开启4个进程
threads=4
for ((i = 0; i < ${threads}; i++)); do
    {
        # 获取锁
        while read -t 1 -u 4; do
            if read -t 1 -u 3 arg; then
                # 释放锁
                echo >&4

                # 任务代码
                task ${arg}
            fi
        done
    } &
done
wait
# 关闭队列和文件描述符
exec 3>&-
exec 4>&-
rm -rf list
rm -rf lock

多进程脚本开启4个子进程同时处理20个任务,一共只需要10s

 

总结:

1.多进程一个关键点就是fifo队列,从队列中没有读取到数据时进程回阻塞

2.给fifo队列添加文件描述符后,插入数据时不会阻塞

3.进程结束的方式选择了read -t,超时后自动退出,这样做逻辑比较简单,如果用主进程信号通知的方式逻辑比较复杂,没有选择那样实现

4.多进程从同一个fifo队列数据默认会有线程安全问题,为此又用了一个队列lock通过加锁解锁解决

5.文件描述符用完记得关闭

 

linux shell多进程

上一篇:Linux安装Docker容器


下一篇:sqlserver 目录名称无效解决办法