您的位置:首页 > 运维架构 > Shell

如何实现shell并发

2015-12-04 16:31 701 查看
很多人都问我如何写shell脚本,如何实现同时给三台ftp服务器上传文件,如何同时检测三台服务器是否alive等,其实这就是想实现shell的并发。那么shell并发该如何实现呢?
下面我就拿这个例子来讲:

每次任务都是输出字符“bingfa”,并停留一秒钟,共20次。

按照正常思维,脚本应该这样写:

[root@station1 ~]# cat a.sh

#!/bin/bash

for((i=0;i<20;i++))

do

sleep 1

echo "bingfa"

done

[root@station1 ~]# time bash a.sh

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

real 0m20.067s

user 0m0.016s

sys 0m0.031s

[root@station1 ~]#

可以看到执行此脚本大概用了20秒。那么使用shell并发该怎么写,很多人都会想到后台程序,类似如下:

[root@station1 ~]# cat b.sh

#!/bin/bash

for((i=0;i<20;i++))

do

{

sleep 1

echo "bingfa"

}&

done

wait

[root@station1 ~]# time bash b.sh

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

bingfa

real 0m1.060s

user 0m0.005s

sys 0m0.057s

[root@station1 ~]#

这样写只需花大概一秒钟,可以看到所有的任务几乎同时执行,如果任务量非常大,系统肯定承受不了,也会影响系统中其他程序的运行,这样就需要一个线程数量的控制。下面是我一开始写的代码(是有问题的):

[root@station1 ~]# cat c.sh

#!/bin/bash

exec 6<>tmpfile

echo "1\n1\n1" &>6

for((i=0;i<20;i++))

do

read -u 6

{

sleep 1

echo "$REPLY"

echo "1" 1>&6

}&

done

wait

[root@station1 ~]# time bash c.sh

111

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

real 0m1.074s

user 0m0.012s

sys 0m0.031s

[root@station1 ~]#

可以明显看出是有问题的,我本想控制线程个数为3,但是就算文件描述符6中为空,也会被读取空,然后跳过继续下面的执行,所以使用文件描述符打开一个文件是不行的,然后我就想着使用类似管道的文件来做,下面是我的代码:

[root@station1 ~]# cat d.sh

#!/bin/bash

mkfifo fd2

exec 9<>fd2

echo -n -e "1\n1\n1\n" 1>&9

for((i=0;i<20;i++))

do

read -u 9

{ #your process

sleep 1

echo "$REPLY"

echo -ne "1\n" 1>&9

} &

done

wait

rm -f fd2

[root@station1 ~]# time bash d.sh

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

real 0m7.075s

user 0m0.018s

sys 0m0.044s

[root@station1 ~]#

这样就ok了,三个线程运行20个任务,7秒多点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: