北京SEO

linux中shell模拟多线程执行任务详解

2019/10/10/17:45:51  阅读:1785  来源:谷歌SEO算法  标签: SEO

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

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

  1. #!/bin/bash
  2. set-x#开启调试模式
  3. #判断是否有参数
  4. if[$#!=1];then
  5. echo"您输入的参数有误"
  6. exit-1
  7. fi
  8. #允许的最大进程数
  9. MAX_THREAD_NUM=5
  10. tmp_fifo_file=/tmp/$$.fifo#以脚本运行的当前进程ID号作为文件名
  11. mkfifo"$tmp_fifo_file"#新建一个随机fifo管道文件
  12. exec9<>"$tmp_fifo_file"#定义文件描述符9指向这个fifo管道文件
  13. rm"$tmp_fifo_file"
  14. #预先写入指定数量的换行符到fifo管道文件中,一个换行符代表一个进程
  15. for((i=0;i<$MAX_THREAD_NUM;i++));do
  16. echo
  17. done>&9
  18. #循环读出url并判断状态码
  19. whilereadline
  20. do
  21. {
  22. #进程控制
  23. read-u9#从文件描述符9中读取行,实际指向fifo管道
  24. {
  25. isok=`curl-I-L-m60-o/dev/null-s-w%{http_code}$line`
  26. if["$isok"="200"];then
  27. echo$line"OK"
  28. else
  29. echo$line$isok
  30. fi
  31. echo>&9#,当前进程结束,往fifo管道文件中写入一个空行
  32. }&//phpfensi.com
  33. }
  34. done<$1waitecho'执行结束'exec9>&-#删除文件描述符9
  35. exit0

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

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

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

  1. #bashscanUrl.shurl.txt
  2. +'['1'!='1']'
  3. +MAX_THREAD_NUM=5
  4. +tmp_fifo_file=/tmp/phpfensi.com
  5. +mkfifo/tmp/phpfensi.com
  6. +exec
  7. +rm/tmp/phpfensi.com
  8. +((i=0))
  9. +((i<5))
  10. +echo
  11. +((i++))
  12. +((i<5))
  13. +echo
  14. +((i++))
  15. +((i<5))
  16. +echo
  17. +((i++))
  18. +((i<5))
  19. +echo
  20. +((i++))
  21. +((i<5))
  22. +echo
  23. +((i++))
  24. +((i<5))
  25. +readline
  26. +read-u9
  27. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /
  28. +readline
  29. +read-u9
  30. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /
  31. +readline
  32. +read-u9
  33. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /
  34. +readline
  35. +read-u9
  36. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /
  37. +readline
  38. +read-u9
  39. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /
  40. +readline
  41. +read-u9#fifo文件中的5个空行读完了,等待其它子进程写入fifo
  42. +isok=200
  43. +'['200=200']'
  44. +echohttp://phpfensi.com /OK
  45. http://phpfensi.com/OK
  46. +echo#这个子进程完成任务,写入fifo一个空行,启动一个子进程
  47. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /
  48. +readline
  49. +read-u9
  50. +isok=200
  51. +'['200=200']'
  52. +echohttp://50vip.com/OK
  53. http://50vip.com/OK
  54. +echo
  55. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /info/
  56. +readline
  57. +read-u9
  58. +isok=200
  59. +'['200=200']'
  60. +echohttp://361a.net/OK
  61. http://361a.net/OK
  62. +echo
  63. ++curl-I-L-m60-o/dev/null-s-w'%{http_code}'http://phpfensi.com /
  64. +readline
  65. +wait#输入文件中的url都已经处理完成或在子进程中处理,等待所有子进程结束
  66. +isok=200
  67. +'['200=200']'
  68. +echohttp://phpfensi.com /OK
  69. http://phpfensi.com /OK
  70. +echo
  71. +isok=000
  72. +'['000=200']'
  73. +echohttp://5imovie.org/000
  74. http://5imovie.org/000
  75. +echo
  76. +isok=200
  77. +'['200=200']'
  78. +echohttp://phpfensi.com /OK
  79. http://52ixwebhosting.com/OK
  80. +echo
  81. +isok=404
  82. +'['404=200']'
  83. +echohttp://phpfensi.com /info/404
  84. http://phpfensi.com /info/404
  85. +echo
  86. +isok=000
  87. +'['000=200']'
  88. +echohttp://phpfensi.com /000
  89. http://42.hcocoa.com/000
  90. +echo
  91. +echo$'346211247350241214347273223346235237'
  92. 执行结束
  93. +exec
  94. +exit0

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

  1. #!/bin/bash
  2. functionpinghost{
  3. ping$1-c1-w10|greprtt|cut-d“/”-f6
  4. }
  5. tmp_fifofile=”/tmp/$.fifo”#脚本运行的当前进程ID号作为文件名
  6. mkfifo$tmp_fifofile#新建一个随机fifo管道文件
  7. exec6<>$tmp_fifofile#定义文件描述符6指向这个fifo管道文件
  8. rm$tmp_fifofile
  9. thread=10
  10. for((i=0;i<$thread;i++));do#for循环往fifo管道文件中写入10个空行
  11. echo
  12. done>&6
  13. whilereaddomain
  14. do
  15. read-u6#从文件描述符6中读取行(实际指向fifo管道)
  16. {
  17. pinghost${domain};#执行pinghost函数
  18. echo>&6#再次往fifo管道文件中写入一个空行。
  19. }&#放到后台执行
  20. done</home/miotour/ip.txt
  21. wait#因为之前的进程都是后台执行,因此要有wait来等待所有的进程都执行完毕后才算整个脚本跑完。
  22. exec6>&-#删除文件描述符6
  23. exit0

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

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

广告内容

linux中shell模拟多线程执行任务详解 linux中shell模拟多线程执行任务详解 linux中shell模拟多线程执行任务详解

相关阅读

热门评论

小明SEO博客 小明SEO博客

小明SEO博客,新时代SEO博客

总篇数171

精选文章

RMAN中catalog和nocatalog区别介绍 小技巧:为Linux下的文件分配多个权限 zimbra8.5.1安装第三方签名ssl证书的步骤 解决mysql不能远程连接数据库方法 windows服务器mysql增量备份批处理数据库 mysql中slow query log慢日志查询分析 JavaScript跨域问题总结 Linux下负载均衡软件LVS配置(VS/DR)教程 mysql中权限参数说明 MYSQL(错误1053)无法正常启动

SEO最新算法