代码之家  ›  专栏  ›  技术社区  ›  daxim Fayland Lam

readline挂在手动管道上()

  •  3
  • daxim Fayland Lam  · 技术社区  · 6 年前

    # 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->自动冲洗(1)
    • 显式退出
    • 检查strace-ff以查看是否错过了一个重要的系统调用

    1 回复  |  直到 6 年前
        1
  •  3
  •   Shawn    6 年前

    pipe 之前 fork 这两个进程都有读写文件描述符的打开副本,因此父进程中的读循环将阻塞等待更多的输入,而这些输入永远不会来自仍然打开的写端。

    子进程需要 close $r; ,父进程需要 close $w;