linux - 如何循环传输管道中的数据?

标签 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. 每个程序打开的读/写管道数量是否有限制?例如。如果我 fork 10 个进程并有 20 个管道(10 个读/10 个写),这是一个坏主意吗?

如果问题太基础,我很抱歉,但我的经验是使用另一种语言的线程。

最佳答案

有一些重要的警告( * ),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 个管道不会成为问题。

*一个重要的警告是管道的缓冲区较小,在某些操作系统上非常小。如果填充此缓冲区,则管道的写入端可能会阻塞写入操作,直到读取端从缓冲区中取出某些内容。如果您不仔细管理读取和写入,您的程序可能会死锁。

关于linux - 如何循环传输管道中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22999497/

相关文章:

linux - 套接字中缓冲区大小的用途是什么?

c - 如何知道中断后内核开始执行的时间?

perl - 如何在 Gtk3::TreeViewColumn 中设置背景颜色?

regex - Perl 正则表达式 : Does the at sign @ need to be escaped?

java - 在单独的连续行中打印 3 个 JAVA 程序的输出,共享同一控制台,在多处理场景中使用\r

javascript - Javascript 中的父目录文件路径在 Linux 中不起作用

Linux:获取 "user-friendly"网络接口(interface)名称

perl - 在 Perl 中美化/美化 HTML

python3如何在应用error_callback时找出apply_async目标函数中的哪一行导致错误

python - 多处理 AttributeError 模块对象没有属性 '__path__'