如何实现shell并发
2013-12-06 14:58
204 查看
很多人都问我如何写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秒多点。
转自:http://blog.chinaunix.net/uid-27571599-id-3473078.html
下面我就拿这个例子来讲:
每次任务都是输出字符“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秒多点。
转自:http://blog.chinaunix.net/uid-27571599-id-3473078.html
相关文章推荐
- 如何实现shell并发
- 如何实现shell并发 一个入门级可控多线程shell脚本方案
- 如何实现shell并发 一个入门级可控多线程shell脚本方案
- 如何快速实现高并发短文检索
- Linux学习-->如何通过Shell脚本实现发送邮件通知功能?
- 如何实现超高并发的无锁缓存?
- 如何利用Redis分布式锁实现控制并发
- shell如何实现ssh免密码登陆
- 如何在emacs中打开shell模式时实现shell命令记忆功能
- 如何快速实现高并发短文检索
- 互联网架构如何实现“高并发”
- java并发编程:如何实现生产者消费者模式?
- 深入分析虚拟机创建对象的两种方式以及如何在并发情况下实现线程安全
- 技术揭秘一:12306是如何实现高流量高并发的关键技术?
- Git学习-->如何通过Shell脚本实现 监控Gitlab备份整个过程并且通过邮件通知得到备份结果?
- MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能
- 如何用shell实现基本的线程池
- Nginx 多进程模型是如何实现高并发的?
- Shell文件描述符传参并发,以不通过队列的形式实现队列
- WCF单例服务,如何实现并发