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  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  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  in  ` cat  $ file `; 
do
     read  -u4  #从管道中读取行,每次一行,所有行读取完毕后挂起,直到管道有空闲的行
     {
     curl -s $i &>  /dev/null  
     sleep  0.1  #暂停0.1s给系统缓冲时间,达到限制并发进程数量
     echo  ""  >&4
     }&  #放入后台运行
done
wait  #等待所有后台进程执行完成
}
for  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,如需转载请自行联系原作者