加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux中shell模拟多线程执行任务介绍

发布时间:2023-07-22 13:11:57 所属栏目:Linux 来源:
导读:多线程是对于linux系统来讲是小菜了,下面小编为各位整理一篇linux中shell模拟多线程执行任务详解,希望文章可以帮助到各位。shell本身是不能实现多线程的,但是可以通过启动子进程,并将子进程放入后台执行来模拟多线程

多线程是对于linux系统来讲是小菜了,下面小编为各位整理一篇linux中shell模拟多线程执行任务详解,希望文章可以帮助到各位。

shell本身是不能实现多线程的,但是可以通过启动子进程,并将子进程放入后台执行来模拟多线程,为了在提高脚本执行效率的同时又不明显增加负载的作用,还需要对同时放入后台的进程数做下限制,代码如下:

#!/bin/bash 

set -x  # 开启调试模式 

#判断是否有参数 

if [ $# != 1 ];then 

    echo "您输入的参数有误" 

    exit -1 

fi 

# 允许的最大进程数 

MAX_THREAD_NUM=5 

tmp_fifo_file=/tmp/$$.fifo # 以脚本运行的当前进程ID号作为文件名 

mkfifo "$tmp_fifo_file"    # 新建一个随机fifo管道文件 

exec 9<>"$tmp_fifo_file"   # 定义文件描述符9指向这个fifo管道文件 

rm "$tmp_fifo_file" 

# 预先写入指定数量的换行符到fifo管道文件中,一个换行符代表一个进程 

for((i=0;i<$MAX_THREAD_NUM;i++));do 

     echo  

done >&9 

# 循环读出url并判断状态码 

while read line 

do 

    # 进程控制 

    read -u 9 # 从文件描述符9中读取行,实际指向fifo管道 

    { 

        isok=`curl -I -L -m 60 -o /dev/null -s -w %{http_code} $line` 

        if [ "$isok" = "200" ];then 

            echo $line "OK" 

        else 

            echo $line $isok 

        fi 

        echo >&9 # ,当前进程结束,往fifo管道文件中写入一个空行 

    }&  //Cuoxin.com 

done < $1 wait echo '执行结束' exec 9>&- # 删除文件描述符9 

exit 0 

脚本的任务是对一个url列表中的网址进行判断,判断这些网址是否可以继续访问,具体方法是,通过curl获取http的状态码来判断.

上面红色部分{}中的语句被放进子进程中在后台执行,当fifo中5个空行读完后,循环继续等待 read 中读取fifo数据,当后台的子进程完成任务后,排队往fifo输入空行,这样fifo中又有了数据,循环继续执行.

下面看看shell执行的结果,代码如下:

# bash scanUrl.sh url.txt  

+ '[' 1 '!=' 1 ']' 

+ MAX_THREAD_NUM=5 

+ tmp_fifo_file=/tmp/Cuoxin.com 

+ mkfifo /tmp/Cuoxin.com 

+ exec 

+ rm /tmp/Cuoxin.com 

+ (( i=0 )) 

+ (( i<5 )) 

+ echo 

+ (( i++ )) 

+ (( i<5 )) 

+ echo 

+ (( i++ )) 

+ (( i<5 )) 

+ echo 

+ (( i++ )) 

+ (( i<5 )) 

+ echo 

+ (( i++ )) 

+ (( i<5 )) 

+ echo 

+ (( i++ )) 

+ (( i<5 )) 

+ read line 

+ read -u 9 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com / 

+ read line 

+ read -u 9 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com / 

+ read line 

+ read -u 9 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com / 

+ read line 

+ read -u 9 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com / 

+ read line 

+ read -u 9 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com / 

+ read line 

+ read -u 9      # fifo文件中的5个空行读完了,等待其它子进程写入fifo 

+ isok=200 

+ '[' 200 = 200 ']' 

+ echo http://Cuoxin.com / OK 

http://Cuoxin.com / OK 

+ echo          # 这个子进程完成任务,写入fifo一个空行,启动一个子进程 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com / 

+ read line 

+ read -u 9 

+ isok=200 

+ '[' 200 = 200 ']' 

+ echo http://50vip.com/ OK 

http://50vip.com/ OK 

+ echo 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com /info/ 

+ read line 

+ read -u 9 

+ isok=200 

+ '[' 200 = 200 ']' 

+ echo http://361a.net/ OK 

http://361a.net/ OK 

+ echo 

++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://Cuoxin.com / 

+ read line 

+ wait         # 输入文件中的url都已经处理完成或在子进程中处理,等待所有子进程结束 

+ isok=200 

+ '[' 200 = 200 ']' 

+ echo http://Cuoxin.com / OK 

http://Cuoxin.com / OK 

+ echo 

+ isok=000 

+ '[' 000 = 200 ']' 

+ echo http://5imovie.org/ 000 

http://5imovie.org/ 000 

+ echo 

+ isok=200 

+ '[' 200 = 200 ']' 

+ echo http://Cuoxin.com / OK 

http://52ixwebhosting.com/ OK 

+ echo 

+ isok=404 

+ '[' 404 = 200 ']' 

+ echo http://Cuoxin.com /info/ 404 

http://Cuoxin.com /info/ 404 

+ echo 

+ isok=000 

+ '[' 000 = 200 ']' 

+ echo http://Cuoxin.com / 000 

http://42.hcocoa.com/ 000 

+ echo 

+ echo $'346211247350241214347273223346235237' 

执行结束 

+ exec 

+ exit 0 

下面我们再来看个例子,代码如下:

#!/bin/bash 

function pinghost { 

ping $1 -c 1 -w 10 |grep rtt|cut -d “/” -f6 

tmp_fifofile=”/tmp/$.fifo”   # 脚本运行的当前进程ID号作为文件名 

mkfifo $tmp_fifofile         # 新建一个随机fifo管道文件 

exec 6<>$tmp_fifofile         # 定义文件描述符6指向这个fifo管道文件 

rm $tmp_fifofile 

thread=10 

for ((i=0;i<$thread;i++));do   # for循环 往 fifo管道文件中写入10个空行 

echo 

done >&6 

while read domain 

do 

read -u6                  # 从文件描述符6中读取行(实际指向fifo管道) 

pinghost ${domain};      # 执行pinghost函数 

echo >&6                      # 再次往fifo管道文件中写入一个空行。 

}&                                  # 放到后台执行 

done</home/miotour/ip.txt 

wait                          #因为之前的进程都是后台执行,因此要有wait来等待所有的进程都执行完毕后才算整个脚本跑完。 

exec 6>&-                #删除文件描述符6 

exit 0 

说明:{} 这部分语句被放入后台作为一个子进程执行,这部分几乎是同时完成的,当fifo中10个空行读完后 while循环.

继续等待 read 中读取fifo数据,当后台的10个子进程后,按次序排队往fifo输入空行,这样fifo中又有了数据,for语句继续执行.

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章