澳门网络娱乐游戏平台-澳门电子游戏娱乐网址-官方直营

新澳门最新官方网址:Linux Shell多线程实现

情景

shell脚本的推行功效虽高,但当任务量庞大时照旧供给较长的日子,尤其是须求进行一大批判的一声令下时。因为暗许情形下,shell脚本中的命令是串行实践的。要是那个命令相互之间是单独的,则能够利用“并发”的措施实行这几个命令,那样能够更加好地使用系统能源,进步周转功效,裁减脚本推行的日子。假诺命令相互之间存在人机联作,则情形就百端待举了,那么不提议采纳shell脚本来实现三十二线程的得以达成。

为了便于解说,使用大器晚成段测验代码。在此段代码中,通过seq指令输出1到10,使用for...in语句发生三个履行10回的大循环。每叁遍巡回都试行sleep 1,并echo出脚下巡回对应的数字。

注意:

  1. 敬业的应用处境下,循环次数不必然等于10,或高或低,具体决定于实际的要求。
  2. 实际的行使情况下,循环体内施行的讲话往往相比较开销系统财富,或比较耗费时间等。

请根据真人真事场景的各类境况清楚本文想要表明的从头到尾的经过

$ cat test1.sh  

#/bin/bash

all_num=10

a=$(date +%H%M%S)

for num in `seq 1 ${all_num}`
do
    sleep 1
    echo ${num}
done

b=$(date +%H%M%S)

echo -e "startTime:t$a"
echo -e "endTime:t$b"

由此上述代码可以见到,为了呈现实践的岁月,将循环体开端左右的小时打印了出去。

运维结果:

$ sh test1.sh 

1
2
3
4
5
6
7
8
9
10
startTime:  193649
endTime:    193659

十二回巡回,每一回sleep 1秒,所以总实施时间10s。

方案

方案1:使用"&"义务令后台运维

在linux中,在指令的最终加上&标记,则表示该命令将要后台试行,那样前面包车型大巴通令不用等待前方的授命推行完就足以起来试行了。示例中的循环体内有多条命令,则能够以{}括起来,在大括号后边增添&符号。

$ cat test2.sh 

#/bin/bash

all_num=10

a=$(date +%H%M%S)

for num in `seq 1 ${all_num}`
do
{
    sleep 1
    echo ${num}
} &
done

b=$(date +%H%M%S)

echo -e "startTime:t$a"
echo -e "endTime:t$b"

运作结果:

sh test2.sh 

startTime:  194147
endTime:    194147
[j-tester@merger142 ~/bin/multiple_process]$ 1
2
3
4
5
6
7
8
9
10

经过结果可以知道,程序还未先打字与印刷数字,而是直接出口了初阶和终止时间,然后呈现出了命令提醒符[j-tester@merger142 ~/bin/multiple_process]$(现身命令提示符表示脚本已运营完成),然后才是数字的输出。那是因为循环体内的通令全体跻身后台,所以均在sleep了1秒今后输出了数字。起首和终结时间同意气风发,即循环体的施行时间不到1分钟,那是由于循环体在后台实行,没有循情枉法脚本主进度的年月。

方案2:命令后台运营+wait命令

化解地点的问题,只须要在上述循环体的done语句前边加上wait命令,该命令等待日前剧本进度下的子进度甘休,再运营后边的口舌。

$ cat test3.sh 

#/bin/bash

all_num=10

a=$(date +%H%M%S)

for num in `seq 1 ${all_num}`
do
{
    sleep 1
    echo ${num}
} &
done

wait

b=$(date +%H%M%S)

echo -e "startTime:t$a"
echo -e "endTime:t$b"

运维结果:

$ sh test3.sh 

1
2
3
4
5
6
7
9
8
10
startTime:  194221
endTime:    194222

但这么依然留存叁个标题:
因为&使得全部循环体内的指令全体进去后台运维,那么后生可畏旦循环的次数过多,会使操作系统在弹指间创立出全部的子进度,那会拾叁分消耗系统的能源。若是循环体内的吩咐又很花费系统财富,则结果简而言之。

最棒的章程是现身的长河是可布署的。

方案3:使用文件陈诉符调节并发数

$ cat test4.sh 

#/bin/bash

all_num=10
# 设置并发的进程数
thread_num=5

a=$(date +%H%M%S)


# mkfifo
tempfifo="my_temp_fifo"
mkfifo ${tempfifo}
# 使文件描述符为非阻塞式
exec 6<>${tempfifo}
rm -f ${tempfifo}

# 为文件描述符创建占位信息
for ((i=1;i<=${thread_num};i++))
do
{
    echo 
}
done >&6 


# 
for num in `seq 1 ${all_num}`
do
{
    read -u6
    {
        sleep 1
        echo ${num}
        echo "" >&6
    } & 
} 
done 

wait

# 关闭fd6管道
exec 6>&-

b=$(date +%H%M%S)

echo -e "startTime:t$a"
echo -e "endTime:t$b"

运作结果:

$ sh test4.sh 

1
3
2
4
5
6
7
8
9
10
startTime:  195227
endTime:    195229

方案4:使用xargs -P调整并发数

xargs命令有一个-P参数,表示扶持的最大进度数,默以为1。为0时期表尽大概地质大学,即方案2的效果。

$ cat test5.sh 

#/bin/bash

all_num=10
thread_num=5

a=$(date +%H%M%S)

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"

运维结果:

$ sh test5.sh 

1
2
3
4
5
6
8
7
9
10
startTime:  195257
endTime:    195259

方案5:使用GNU parallel一声令下调节并发数

GNU parallel一声令下是可怜有力的并行计六柱预测令,使用-j参数调节其冒出数量。

$ cat test6.sh 

#/bin/bash

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"

运营结果:

$ sh test6.sh 

1
2
3
4
5
6
7
8
9
10
startTime:  195616
endTime:    195618

总结

“四十八线程”的平价总来讲之,固然shell中并从未当真的四线程,但上述解决方案得以兑现“八线程”的作用,首要的是,在骨子里编写脚本时应有那样的思考和得以落成。
另外:
方案3、4、5虽说都得以调节并发数量,但方案3名闻遐迩写起来太繁缛。
方案4和5都是老大简洁的花样完结了决定并发数的机能,但出于方案5的parallel命令特别强盛,所以那多少个建议系统学习下。
方案3、4、5安装的并发数均为5,实际编写时得以将该值作为三个参数字传送入。

连带知识点

  • wait命令
  • &后台运维
  • 新澳门最新官方网址,文件描述符、mkfifo等
  • xargs命令
  • parallel命令

本文永世更新链接地址:http://www.linuxidc.com/Linux/2017-06/145162.htm

新澳门最新官方网址 1

本文由澳门网络娱乐游戏平台发布于操作系统,转载请注明出处:新澳门最新官方网址:Linux Shell多线程实现

相关阅读