免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5936 | 回复: 6
打印 上一主题 下一主题

求助:在perl线程里调用shell命令获取输出问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-20 15:52 |只看该作者 |倒序浏览
有没有人碰到过这种情况
在perl线程里执行shell命令(打比方,如cat),因为想直接获取命令打印信息,用的是``
但线程会阻塞在所执行命令那(出现概率很大)

我现在写了测试脚本,只是cat个100来K的文件,就会停在那,代码如下:

#!/usr/bin/perl -w


use strict;
use vars qw / @thrs /;
use threads;
use threads::shared;

my $thr_num = $ARGV[2] || 10;    # 创建的线程数目
my $file_name = $ARGV[1];        # 线程里cat命令打开的文件
my $count:shared;                # 执行命令的总次数


$count = $ARGV[0]||100;

for (1..$thr_num) {
    push(@thrs, threads->new(\&thread_req));
}

for (@thrs) {
    $_->join();
    print $_->tid()." join\n";
}

sub thread_req {
    LOOP:
    while (1) {
        my $id;
        {
            lock($count);
            last LOOP if ($count == 0);
            $id = $count--;
        }
        print "--", threads->tid(), " count=$count\n";
        `cat $file_name`;        # 线程会停在这
    }
    print "--", threads->tid(), " ok\n";
}


这样执行命令,test.txt大小为 80158 Byte:
[root@ns4 ~]# ./test_multi4.pl 50  test.txt 5
--1 count=49
--2 count=48
...
--5 count=0
--5 ok
--4 ok
到这就停住了

查看进程可以看到:
89-root     22149  0.0  0.2  7664 2552 ?        Ss   14:50   0:01  \_ sshd: [email=root@pts/7]root@pts/7[/email]
90-root     22154  0.0  0.1  6576 1676 pts/7    Ss   14:50   0:00      \_ -bash
91:root      2130  0.0  0.4 62404 4404 pts/7    Sl+  15:29   0:00          \_ /usr/bin/perl -w ./test_multi4.pl 50 test.txt 5
92:root      2179  0.0  0.0  5904  416 pts/7    S+   15:29   0:00              \_ cat test.txt
93:root      2180  0.0  0.0  5320  416 pts/7    S+   15:29   0:00              \_ cat test.txt
94:root      2178  0.0  0.0  6016  416 pts/7    S+   15:29   0:00              \_ cat test.txt

不明白为什么会这样,似乎只要执行的shell命令有较多的打印信息,就会出现这种情况
但是单个线程的话,我试了很多遍都没出现
另外,若用system函数调用,我测了很多次也没有出现这种情况

能否帮忙看下问题所在,谢谢:)

[ 本帖最后由 iceberg77 于 2008-10-20 18:12 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-10-24 09:09 |只看该作者
原帖由 iceberg77 于 2008-10-20 15:52 发表
有没有人碰到过这种情况
在perl线程里执行shell命令(打比方,如cat),因为想直接获取命令打印信息,用的是``
但线程会阻塞在所执行命令那(出现概率很大)

我现在写了测试脚本,只是cat个100来K的文件,就 ...



真的没人知道怎么回事么

论坛徽章:
0
3 [报告]
发表于 2008-10-24 09:56 |只看该作者
原帖由 iceberg77 于 2008-10-24 09:09 发表



真的没人知道怎么回事么


听很多人说  perl的线程不安全

论坛徽章:
0
4 [报告]
发表于 2008-10-26 14:50 |只看该作者
估计是多线程并发状态下,``操作符捕获STDOUT输出时,或者说PIPE连接时冲突(撞车)了。
如果真是这样,该现象就跟并发写一个文件时产生的冲突一样了。

挺有趣的,难道该例子中,也需要一个lock?

期待更好的解释。  ;-p

论坛徽章:
0
5 [报告]
发表于 2011-12-08 15:35 |只看该作者
反引号会迫使perl捕获cat的输出结果,这可能会引起安全问题。
所以你可以尝试使用 system "cat $file_name"; 替换反引号语句,在测试是否会出现你遇到的情况

论坛徽章:
0
6 [报告]
发表于 2011-12-08 16:18 |只看该作者
open F, "cat $file";
while(<F>) {
     chomp;
     ....;
}
close(EXEC_SH) or $? >>= 8;

论坛徽章:
0
7 [报告]
发表于 2011-12-08 16:22 |只看该作者
system是将其输出的结果传到Perl 标准输出的地方。应该是有一行输出一行吧

反引号,是将命令执行完之后一次性将输出返回,所以文件大了会卡一会

用open就可以有一行读一行,直到命令执行完毕了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP