Bash之多线程模型
shell多线程支持
一、单线程的shell
cat test.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
http://blog.
51
cto.com/hmtk
520
/
1943716
http://blog.
51
cto.com/hmtk
520
/
1944156
http://blog.
51
cto.com/hmtk
520
/
1944015
http://blog.
51
cto.com/hmtk
520
/
1944004
http://blog.
51
cto.com/hmtk
520
/
1943976
http://blog.
51
cto.com/hmtk
520
/
1943953
http://blog.
51
cto.com/hmtk
520
/
1967968
http://blog.
51
cto.com/hmtk
520
/
1950172
http://blog.
51
cto.com/hmtk
520
/
1950170
http://blog.
51
cto.com/hmtk
520
/
1950157
http://blog.
51
cto.com/hmtk
520
/
1950148
http://blog.
51
cto.com/hmtk
520
/
1942867
http://blog.
51
cto.com/hmtk
520
/
1942866
http://blog.
51
cto.com/hmtk
520
/
1941762
http://blog.
51
cto.com/hmtk
520
/
1941755
http://blog.
51
cto.com/hmtk
520
/
1941732
http://blog.
51
cto.com/hmtk
520
/
1941721
http://blog.
51
cto.com/hmtk
520
/
1941652
http://blog.
51
cto.com/hmtk
520
/
1941650
http://blog.
51
cto.com/hmtk
520
/
1941644
|
1
2
3
4
5
|
[root@node112
test
]
# sum=0 ;time while read line ; do curl -s $line &> /dev/null && let sum++ ;done < test.html ;echo $sum
real 0m5.960s
user 0m0.113s
sys 0m0.158s
20
|
//直接使用curl命令访问的话,需要5s多
1
2
3
4
|
[root@node112
test
]
# time for i in `cat test.html `;do curl -s $i &> /dev/null ;done
real 0m5.386s
user 0m0.122s
sys 0m0.138s
|
串行执行效率较低而且较慢。
二、升级使用多线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
[root@node112
test
]
# time ./thread.html test.html
Ok
...
Ok
real 0m0.594s
user 0m0.067s
sys 0m0.113s
//
耗时1s不到
[root@node112
test
]
# cat thread.html
#!/bin/bash
while
read
line
do
{
curl -s $line &>
/dev/null
&&
echo
Ok
} &
done
< $1
wait
//
等待所有线程执行完毕后退出,在第一个线程执行完毕后就会退出。
[root@node112
test
]
# cat thread.html //这样也可以
#!/bin/bash
for
i
in
`
cat
.
/test
.html` ;
do
{
curl -s $i &>
/dev/null
&&
echo
Ok
} &
done
wait
|
使用&和wait实现
三、多线程问题
但有个问题是进程会一下子非常多,几百上千,超过系统限制报错,需要对进程数控制。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#!/bin/bash
file
=.
/index
.html
thread_num=50
# 自定义并发数,根据服务器性能或应用性能调整大小,别定义太大,太大可能会导致系统宕机
tmp_fifo_file=
/tmp/
$$.fifo
#以进程ID号命名的管道文件
mkfifo
$tmp_fifo_file
#创建临时管道文件
exec
4<>$tmp_fifo_file
#以rw方式打开tmp_fifo_file管道文件,文件描述符为4,也可以取3-9的任意描述符
rm
-f $tmp_fifo_file
#删除临时管道文件,也可以不删除
for
((i=0;i<$thread_num;i++))
#利用for循环向管道中输入并发数量的空行
do
echo
""
#输出空行
done
>&4
#输出重定向到定义的文件描述符4上
for
i
in
`
cat
$
file
`;
do
read
-u4
#从管道中读取行,每次一行,所有行读取完毕后挂起,直到管道有空闲的行
{
curl -s $i &>
/dev/null
&&
echo
$i
sleep
0.1
#暂停0.1s给系统缓冲时间,达到限制并发进程数量
echo
""
>&4
}&
#放入后台运行
done
wait
#等待所有后台进程执行完成
exit
0
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
[root@node112
test
]
# cat bingfa.sh
#!/bin/bash
file
=.
/index
.html
thread_num=50
# 自定义并发数,根据服务器性能或应用性能调整大小,别定义太大,太大可能会导致系统宕机
tmp_fifo_file=
/tmp/
$$.fifo
#以进程ID号命名的管道文件
mkfifo
$tmp_fifo_file
#创建临时管道文件
exec
4<>$tmp_fifo_file
#以rw方式打开tmp_fifo_file管道文件,文件描述符为4,也可以取3-9的任意描述符
rm
-f $tmp_fifo_file
#删除临时管道文件,也可以不删除
for
((i=0;i<$thread_num;i++))
#利用for循环向管道中输入并发数量的空行
do
echo
""
#输出空行
done
>&4
#输出重定向到定义的文件描述符4上
function
curl_url() {
for
i
in
`
cat
$
file
`;
do
read
-u4
#从管道中读取行,每次一行,所有行读取完毕后挂起,直到管道有空闲的行
{
curl -s $i &>
/dev/null
sleep
0.1
#暂停0.1s给系统缓冲时间,达到限制并发进程数量
echo
""
>&4
}&
#放入后台运行
done
wait
#等待所有后台进程执行完成
}
for
j
in
{1..200};
do
curl_url &&
echo
"$j times succeed"
done
exit
0
[root@node112
test
]
# while read line ; do echo $line ; done < index.html
[root@node112
test
]
# while read line ; do curl -s $line &> /dev/null && echo finished ; done < index.html //正常可以运行
[root@node112
test
]
# while read line ; do { curl -s $line &> /dev/null && echo finished } ; done < index.html //这样是不能运行的
本文转自MT_IT51CTO博客,原文链接:http://blog.51cto.com/hmtk520/2051308,如需转载请自行联系原作者
|