如何循环管道中的数据?

时间:2014-04-10 21:36:50

标签: linux perl multiprocessing fork pipe

我发现了一些代码,Perl中的2个进程可以通过管道进行通信。示例:

if ($pid = fork) {  
      close $reader;  
      print $writer "Parent Pid $$ is sending this\n";  
      close $writer;  
      waitpid($pid,0);   
}   
else {  
      close $writer;  
      chomp($line = <$reader>);  
      print "Child Pid $$ just read this: `$line'\n";  
      close $reader;  
      exit;  
}   

现在我有以下问题:

  1. 是否可以从管道中读取读取器,然后阻塞直到新数据来自管道,就像在循环中一样?
  2. 如果是,当父进程没有要发送的数据时,杀死子进程的方法是什么?
  3. 每个程序有多少个打开的读/写管道有限制吗?例如。如果我分叉10个进程并且有20个管道(10个读/ 10个写),这是个坏主意吗?
  4. 如果问题太基础我很抱歉,但我的经验是使用其他语言的线程。

1 个答案:

答案 0 :(得分:3)

有一些重要的警告(*),Perl中管道的I / O与任何其他文件句柄的I / O非常相似。 readline<>)运算符将等待来自套接字或STDIN的管道上的输入。当您close管道的写入结束时,读取端将接收文件结尾(readline将返回undef)。我可以通过对您的脚本进行一些小的修改来演示这些概念:

pipe $reader, $writer;

if ($pid = fork) {  
      close $reader;  
      sleep 5;
      for (1..10) {
          print $writer "Parent Pid $$ is sending this\n";  
      }
      close $writer;  
      waitpid($pid,0);   
}   
else {  
      close $writer;  
      # <$reader> will block until parent produces something
      # and will return undef when parent closes the write end of the pipe
      while ($line = <$reader>) {
          chomp($line);
          print "Child Pid $$ just read this: `$line'\n";  
      }
      close $reader;  
      exit;  
}

3 进程中通常会有一个操作系统强加的limit on the number of open filehandles,并且打开的管道句柄会计入此值,但10或20个管道不会成为问题。

*一个重要的警告是管道具有的小缓冲区大小,在某些操作系统上限制很小。如果填充此缓冲区,则管道的写入端可能会阻止写入操作,直到读取结束从缓冲区中取出某些内容。如果您不仔细管理您的读写,您的程序可能会陷入僵局。