shell多线程支持
一、单线程的shell
cat test.html

https://blog.51cto.com/hmtk520/1943716
https://blog.51cto.com/hmtk520/1944156
https://blog.51cto.com/hmtk520/1944015
https://blog.51cto.com/hmtk520/1944004
https://blog.51cto.com/hmtk520/1943976
https://blog.51cto.com/hmtk520/1943953
https://blog.51cto.com/hmtk520/1967968
https://blog.51cto.com/hmtk520/1950172
https://blog.51cto.com/hmtk520/1950170
https://blog.51cto.com/hmtk520/1950157
https://blog.51cto.com/hmtk520/1950148
https://blog.51cto.com/hmtk520/1942867
https://blog.51cto.com/hmtk520/1942866
https://blog.51cto.com/hmtk520/1941762
https://blog.51cto.com/hmtk520/1941755
https://blog.51cto.com/hmtk520/1941732
https://blog.51cto.com/hmtk520/1941721
https://blog.51cto.com/hmtk520/1941652
https://blog.51cto.com/hmtk520/1941650
https://blog.51cto.com/hmtk520/1941644
[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多

[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

串行执行效率较低而且较慢。

二、升级使用多线程

[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实现

三、多线程问题
但有个问题是进程会一下子非常多,几百上千,超过系统限制报错,需要对进程数控制。

#!/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
[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 //这样是不能运行的