我正在尝试消除 open 的魔法叉变体:

# magic-fork.pl
if (open my $fh, '-|') { # fork self, make new fd for reading, attach child STDOUT to it
    STDOUT->say('parent getpid: ', $$);
    STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
    STDOUT->say('parent $fh->fileno: ', $fh->fileno);
    while (my $line = $fh->getline) {
        STDOUT->print('parent readline from child: ', $line);
    }
} else {
    STDOUT->say('child getpid: ', $$);
    STDOUT->say('child STDOUT->fileno: ', STDOUT->fileno);
}

它运行并完成。
# plain-fork.pl
pipe my $r, my $w;
if (fork) {
    STDOUT->say('parent getpid: ', $$);
    STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
    STDOUT->say('parent $r->fileno: ', $r->fileno);
    STDOUT->say('parent $w->fileno: ', $w->fileno);
    while (my $line = $r->getline) {
        STDOUT->print('parent readline from child: ', $line);
    }
} else {
    $w->say('child getpid: ', $$);
    $w->say('child $r->fileno: ', $r->fileno);
    $w->say('child $w->fileno: ', $w->fileno);
    $w->say('child STDOUT->fileno: ', STDOUT->fileno);
}

该程序意外卡在循环中。

我试过无济于事:
  • 调用 $w->autoflush(1)
  • 显式关闭句柄
  • 显式退出
  • POSIX::dup2 $w 到 STDOUT
  • 检查 strace -ff 以查看我是否错过了关键的系统调用

  • 有什么问题?

    最佳答案

    您在 pipe ing 之前使用 fork(就像这种 IPC 的通常情况),因此两个进程都有读取和写入文件描述符的打开副本,因此父级中的读取循环只会阻塞等待更多输入,这些输入永远不会来自静止-打开写结束。

    子进程需要 close $r; ,父进程需要 close $w; 在它们各自块的开始处(或者在你打印出这些句柄的文件描述符之后)。

    关于perl - readline 卡在手动管道上(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53372637/

    10-13 07:26