【问题标题】:Perl's waitpid() and IPC::Open2 in Windows vs. Linux/UNIXWindows 与 Linux/UNIX 中的 Perl 的 waitpid() 和 IPC::Open2
【发布时间】:2012-08-14 05:27:18
【问题描述】:

以下代码在 Linux 中完美运行,但是当我将它放在 Windows 机器上时,一切都崩溃了:

$pid = open2($my_reader, $my_writer, "$JAVACALL $PARSER_CP $PARSER_CMD -");
$my_reader->autoflush(1);
$my_writer->autoflush(1);
print $my_writer "$line\n";
close($my_writer);
my $tree = <$my_reader>;
chomp($tree);
push @parse_trees, $tree;
close($my_reader);
waitpid($pid, 0);

在 Windows 中,它只是挂起等待waitpid($pid, 0)。如果我们注释掉该行,一切都会正常完成,但是我们会留下许多孤立的进程。让我感到困惑的是,ActiveState(我们正在使用的 Perl)实际上是 says 以完全按照我们的方式做事。

有没有人知道 Windows 愉快的方式来做到这一点?即使我必须维护两个不同版本的代码,我也不会在意这一点。 :)

(对于那些好奇的人,这段代码会打开Stanford Parser,它接受一个文件作为输入(因此使用“-”(类似于/相同于Linux中的/dev/stdin)),向它抛出一个句子,并取回解析树。不重要,但我知道有人会问。:))

【问题讨论】:

  • 这可能是个问题:perldoc.perl.org/perlport.html#waitpid
  • 你有什么 Windows 版本?我在 Win XP 上使用这种方法没有问题。
  • 既然你说如果你离开那一行就会得到孤立的进程,大概子进程没有退出,这就是你需要诊断的问题。也许 Perl 在行尾发出 LF 而 Java 应该是 CRLF,反之亦然?
  • @squiguy 是的,我确实看到了。我一直在尝试想出一种方法来使用 system()/etc 来代替管道,但是我需要在我的进程和那个进程的 STDIN 之间建立一个连接。
  • @pmod 真的吗?我们有 Windows Server 2008 r2。如果您愿意分享(并且与我所做的完全不同),我会对您所做的确切内容感兴趣。

标签: windows linux perl ipc


【解决方案1】:

好吧,对于那些好奇的人,我让事情按照他们应该的方式工作,但我对修复的一部分并不太着迷。我加了

use POSIX ":sys_wait_h";

并将 waitpid() 调用更改为

waitpid($pid, &WNOHANG);

仅此一项并没有做到,所以在此之后我立即添加了

kill(-9, ($pid));

杀死进程。不是很喜欢对kill() 的调用,但它确实有效,而且奇怪的是,如果我不调用waitpid(),我仍然有僵尸进程。同样,如果有人知道更优雅的解决方案,那就太好了,但现在必须这样做。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    相关资源
    最近更新 更多