免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2045 | 回复: 10

[学习共享] 为什么多线程的shell不能在判断中使用exit命令 [复制链接]

论坛徽章:
0
发表于 2019-05-25 17:47 |显示全部楼层
本帖最后由 yexingqi 于 2019-05-25 17:50 编辑

发现一个很奇怪的问题,向精通shell的大侠们请教。我有如下多线程检查网页状态的一个脚本。简单来说就是多线程检查所有网页的状态并返回值。
如下: 我这里定义为2个线程同时工作

运行方法 run.sh url.txt
-----------------------------------
#!/bin/bash
#允许的进程数
THREAD_NUM=2
#定义描述符为9的管道
tmp_fifo_file=/tmp/$$.fifo
mkfifo "$tmp_fifo_file"
exec 9<>"$tmp_fifo_file"
#预先写入指定数量的换行符,一个换行符代表一个进程
for ((i=0;i<$THREAD_NUM;i++))
do
    echo -ne "\n" 1>&9
done

if [ $# != 1 ] ;then
        echo "The parameters you enter is not correct !";
        exit -1;
fi

while read line
do
{
    #进程控制
    read -u 9
    {
        isok=`curl -I -o /dev/null -s -w %{http_code} $line`
        if [ "$isok" = "200" ]; then
            echo $line "OK"
                elif [ "$isok" = "302" ]; then
                        echo $line "OK2"
                elif [ "$isok" = "000" ]; then
                        echo $line "no_OK"
                        exit 0
        else
            echo $line "no" $isok
        fi
                #写入一个换行符
        echo -ne "\n" 1>&9
    }&
}
done < $1
wait
echo "执行结束"
rm "$tmp_fifo_file"
-----------------------------------


cat url.txt
http://www.baidu.com
http://site.nihaowang.com
https://www.jb51.net
http://bbs.chinaunix.net
http://www.163.com
http://www.sina.com.cn
http://www.baidu.com
http://site.nihaowang.com
https://www.jb51.net
http://bbs.chinaunix.net
http://www.163.com
http://www.baidu.com
http://site.nihaowang.com
https://www.jb51.net
http://bbs.chinaunix.net
http://www.163.com
http://www.baidu.com
https://www.jb51.net
http://bbs.chinaunix.net
http://www.sina.com.cn
http://www.google.com
http://www.baidu.com
http://site.nihaowang.com
https://www.jb51.net
http://bbs.chinaunix.net
http://www.163.com
http://www.sina.com.cn
http://www.baidu.com
http://www.google.com
http://site.nihaowang.com
https://www.jb51.net


只要我在if 中的判断中,加入退出的exit 命令(红色那一行)。 这段脚本在运行中就会卡死。而如果不加这个exit则一切正常。

请问这是什么原因呢? 怎么修复这个问题呀?  
另外特别说一下,我这个判断只是举个例子。其实真正获得000的返回值是不需要加exit的,这段脚本的判断思路是不正确的。我只是拿这个举个例子。谢谢。


论坛徽章:
0
发表于 2019-05-26 19:51 |显示全部楼层
好难理解。。。 怎么修复这个问题呢? 如果我在一些判断中需要加入退出的命令?

论坛徽章:
7
2016科比退役纪念章
日期:2018-10-24 08:24:0115-16赛季CBA联赛之北控
日期:2019-03-12 14:34:562016科比退役纪念章
日期:2019-04-01 10:33:0915-16赛季CBA联赛之山东
日期:2019-04-17 12:46:3215-16赛季CBA联赛之广夏
日期:2019-05-09 16:40:4015-16赛季CBA联赛之广夏
日期:2019-10-10 15:33:4015-16赛季CBA联赛之辽宁
日期:2019-10-15 08:37:06
发表于 2019-05-27 10:46 |显示全部楼层
如果if里的exit 代码执行了,子进程直接退出了,
所以你后面的这句并没有执行到  echo -ne "\n" 1>&9
这句的作用应该是把  命名管道的执行令牌 放回管道,你没有放回令牌,当然就阻塞了,卡住了。

你如果要在if里写exit之类代码,你可以在exit之前都加上一句echo -ne "\n" 1>&9  ,即先把令牌放回去再执行exit.就可以了。

评分

参与人数 1信誉积分 +7 收起 理由
yexingqi + 7 很给力!

查看全部评分

论坛徽章:
0
发表于 2019-05-27 16:06 |显示全部楼层
本帖最后由 本友会机友会摄友会 于 2019-05-27 16:12 编辑

1 bash没有多线程,只有多进程。
python只有假多线程。它的多线程只能用一个cpu内核。
powershell是真正的多线程,多进程脚本。
任何语言,线程,进程都有各自的好处。

2命名管道的执行令牌 放回管道----听的我头大。

3 并发脚本不在于脚本代码,在于数据输入输出。
楼主的我全看不懂。请楼主按照我的思路告诉我:(并发最基本的数据东西)
数据从哪来?怎么输入?并发还是顺序
并发计算完后,
数据到哪去?怎么输出?并发还是顺序。



评分

参与人数 1信誉积分 +5 收起 理由
yexingqi + 5 赞一个!

查看全部评分

论坛徽章:
0
发表于 2019-05-27 20:15 |显示全部楼层
回复 4# cfwyy

多谢多谢指点。 请问一下,我在if 里加exit 0之前放入这个: echo -ne "\n" 1>&9 , 会不会影响我的正在运行多线程呢? 谢谢!

论坛徽章:
0
发表于 2019-05-27 20:17 |显示全部楼层
回复 5# 本友会机友会摄友会

您说得没有错。它并不是严格上的真正多线程。 但毫无疑问它的并发线程能极大帮助我们节省时间。这就足够了。我们写一些小脚本,本身就是为了提交工作效率。节省时间而已。目的达到就行。 不需要太于过介意手法的好坏。

论坛徽章:
7
2016科比退役纪念章
日期:2018-10-24 08:24:0115-16赛季CBA联赛之北控
日期:2019-03-12 14:34:562016科比退役纪念章
日期:2019-04-01 10:33:0915-16赛季CBA联赛之山东
日期:2019-04-17 12:46:3215-16赛季CBA联赛之广夏
日期:2019-05-09 16:40:4015-16赛季CBA联赛之广夏
日期:2019-10-10 15:33:4015-16赛季CBA联赛之辽宁
日期:2019-10-15 08:37:06
发表于 2019-05-28 08:14 |显示全部楼层
回复 6# yexingqi

这个你试一下就知道了

评分

参与人数 1信誉积分 +5 收起 理由
yexingqi + 5 赞一个!

查看全部评分

论坛徽章:
0
发表于 2019-05-28 11:02 |显示全部楼层
回复 8# cfwyy

似乎没有影响.....只是我有点担心,所以想确认一下......

论坛徽章:
0
发表于 2019-05-28 14:27 |显示全部楼层
本帖最后由 本友会机友会摄友会 于 2019-05-28 14:29 编辑
  1. cat a:\pscode\TEMP_2019\temp168\aaa.txt |
  2. ForEach-Object {
  3.         try
  4.         {
  5.                 "{0} -> {1} " -f $_,$((Invoke-WebRequest -TimeoutSec 10 -Uri $_ ).BaseResponse.statuscode)
  6.         }
  7.         catch
  8.         {
  9.          "$_ 失败"
  10.         }
  11. }
复制代码


返回:
http://www.baidu.com -> OK
http://site.nihaowang.com -> OK
https://www.jb51.net -> OK
http://bbs.chinaunix.net -> OK
http://www.163.com -> OK
http://www.sina.com.cn -> OK
http://www.baidu.com -> OK
http://site.nihaowang.com -> OK
https://www.jb51.net -> OK
http://bbs.chinaunix.net -> OK
http://www.163.com -> OK
http://www.baidu.com -> OK
http://site.nihaowang.com -> OK
https://www.jb51.net -> OK
http://bbs.chinaunix.net -> OK
http://www.163.com -> OK
http://www.baidu.com -> OK
https://www.jb51.net -> OK
http://bbs.chinaunix.net -> OK
http://www.sina.com.cn -> OK
操作超时。 失败
http://www.baidu.com -> OK
http://site.nihaowang.com -> OK
https://www.jb51.net -> OK
http://bbs.chinaunix.net -> OK
http://www.163.com -> OK
http://www.sina.com.cn -> OK
http://www.baidu.com -> OK
操作超时。 失败
http://site.nihaowang.com -> OK
https://www.jb51.net -> OK
无效的 URI: 未能分析主机名。 失败
无效的 URI: 未能分析主机名。 失败
无效的 URI: 未能分析主机名。 失败
无效的 URI: 未能分析主机名。 失败

win,linux通用的,单线程!    powershell代码。

论坛徽章:
0
发表于 2019-05-29 20:03 |显示全部楼层
回复 10# 本友会机友会摄友会

单线程的话,太慢了。我如果改用多线程几百个地址也才几秒钟就完成。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,8.5折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时8.5折扣期:2019年9月30日前


----------------------------------------

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP