免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4474 | 回复: 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 |显示全部楼层
好难理解。。。 怎么修复这个问题呢? 如果我在一些判断中需要加入退出的命令?

论坛徽章:
8
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:0615-16赛季CBA联赛之北控
日期:2021-03-30 15:53:34
发表于 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 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

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

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

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

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

论坛徽章:
8
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:0615-16赛季CBA联赛之北控
日期:2021-03-30 15:53:34
发表于 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 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

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

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP