最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
linux中shell模拟多线程执行任务详解
时间:2014-12-04 编辑:简简单单 来源:一聚教程网
shell本身是不能实现多线程的,但是可以通过启动子进程,并将子进程放入后台执行来模拟多线程,为了在提高脚本执行效率的同时又不明显增加负载的作用,还需要对同时放入后台的进程数做下限制。
代码如下 | 复制代码 |
#!/bin/bash #判断是否有参数 # 允许的最大进程数 tmp_fifo_file=/tmp/$$.fifo # 以脚本运行的当前进程ID号作为文件名 # 预先写入指定数量的换行符到fifo管道文件中,一个换行符代表一个进程 # 循环读出url并判断状态码 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/111com.net + mkfifo /tmp/111com.net + exec + rm /tmp/111com.net + (( 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://111com.net / + read line + read -u 9 ++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111com.net / + read line + read -u 9 ++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111com.net / + read line + read -u 9 ++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111com.net / + read line + read -u 9 ++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111com.net / + read line + read -u 9 # fifo文件中的5个空行读完了,等待其它子进程写入fifo + isok=200 + '[' 200 = 200 ']' + echo http://111com.net / OK http://111com.net / OK + echo # 这个子进程完成任务,写入fifo一个空行,启动一个子进程 ++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111com.net / + 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://111com.net /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://111com.net / + read line + wait # 输入文件中的url都已经处理完成或在子进程中处理,等待所有子进程结束 + isok=200 + '[' 200 = 200 ']' + echo http://111com.net / OK http://111com.net / OK + echo + isok=000 + '[' 000 = 200 ']' + echo http://5imovie.org/ 000 http://5imovie.org/ 000 + echo + isok=200 + '[' 200 = 200 ']' + echo http://111com.net / OK http://52ixwebhosting.com/ OK + echo + isok=404 + '[' 404 = 200 ']' + echo http://111com.net /info/ 404 http://111com.net /info/ 404 + echo + isok=000 + '[' 000 = 200 ']' + echo http://111com.net / 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 wait #因为之前的进程都是后台执行,因此要有wait来等待所有的进程都执行完毕后才算整个脚本跑完。 exec 6>&- #删除文件描述符6 exit 0 |
说明:{} 这部分语句被放入后台作为一个子进程执行,这部分几乎是同时完成的,当fifo中10个空行读完后 while循环
继续等待 read 中读取fifo数据,当后台的10个子进程后,按次序排队往fifo输入空行,这样fifo中又有了数据,for语句继续执行。
相关文章
- Linux多线程 创造新线程 线程的生命周期 04-20
- win11内核隔离和内存完整性介绍 10-31
- win10全屏缩放设置教程 10-31
- win10系统备份出错解决教程 10-31
- win10打开软件每次都要询问解决教程 10-31
- win10更新驱动后设备出现异常解决教程 10-31