Bash之多线程模型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bash之多线程模型相关的知识,希望对你有一定的参考价值。

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

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

[[email protected] test]# time for i in `cat test.html `;do curl -s $i &> /dev/null ;done
real    0m5.386s
user    0m0.122s
sys    0m0.138s

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

二、升级使用多线程

[[email protected] test]# time ./thread.html test.html 
Ok
... 
Ok
real    0m0.594s
user    0m0.067s
sys    0m0.113s
//耗时1s不到
[[email protected] test]# cat thread.html 
#!/bin/bash
while read line 
do 
{
    curl -s $line &> /dev/null && echo Ok
} &
done < $1
wait //等待所有线程执行完毕后退出,在第一个线程执行完毕后就会退出。
[[email protected] 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
[[email protected] 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
[[email protected] test]# while read line ; do echo $line ; done < index.html  
[[email protected] test]# while read line ; do  curl -s $line &> /dev/null && echo finished   ; done < index.html //正常可以运行
[[email protected] test]# while read line ; do { curl -s $line &> /dev/null && echo finished } ; done < index.html //这样是不能运行的


以上是关于Bash之多线程模型的主要内容,如果未能解决你的问题,请参考以下文章

python并发编程之多线程守护系列互斥锁生产者消费者模型

android开发之多线程实现方法概述

程序员必备技能之多线程的安全机制

linux网络编程之多进程多线程

Java基础之多线程

TX2之多线程读取视频及深度学习推理