进程挂起,PIPE阻塞

Process hangs and PIPE is blocked

本文关键字:阻塞 PIPE 挂起 进程      更新时间:2023-10-16

我似乎有一个死锁。我有perl脚本分叉并调用另一个perl脚本。并且进程挂在某处。

我正在运行程序:达尔文内核版本12.3.0:Sun Jan 6 22:37:10 PST 2013;根:xnu-2050.22.13 ~ 1/RELEASE_X86_64 x86_64

"lsof"有4个条目指向同一个PIPE:

perl5.12 1414 root 1 PIPE 0x48937dc1254fe937 16384 ->0x48937dc1254fe727

perl5.12 1768 root 1 PIPE 0x48937dc1254fe937 16384 ->0x48937dc1254fe727

perl5.12 1759 root 1 PIPE 0x48937dc1254fe937 16384 ->0x48937dc1254fe727

perl5.12 1760 root 1 PIPE 0x48937dc1254fe937 16384 ->0x48937dc1254fe727

我怀疑那是hang的原因。我们是否有任何命令可以告诉我哪个进程在这个PIPE中读/写?或任何进一步的信息将不胜感激。提前感谢!

我能想到的可能有两种:

  1. 由于输出缓冲导致死锁。尝试在所有输出管道上启用自动刷新。如果两个进程使用管道进行双向通信,则可能出现这种情况:它们各自写入内容并等待读取响应,但由于输出被缓冲,因此响应从未发送到管道。

  2. 一个进程正在等待管道上的EOF,但是它从来没有到来。如果管道是在父进程中创建的,然后由子进程继承,则需要确保所有进程关闭管道的写端,以便读取器读取EOF。

正如Barmar还解释的那样,当输出缓冲区填满时,子进程可能会卡住。在这种情况下,你会发现子进程卡在write()函数调用中。

你必须在父进程中使用Perl IO::Select模块不断地从子进程中读取输出缓冲区,从而在子进程的输出大于缓冲区时清空它。

官方Perl文档在http://perldoc.perl.org/functions/sysread.html解释:

sysread FILEHANDLE,SCALAR,LENGTH
尝试读取长度字节的数据使用read(2)从指定的FILEHANDLE转换为变量SCALAR。它绕过了缓冲的IO,所以将它与其他类型的读取,打印,写,找,告诉,或eof会引起混乱,因为perlio或Stdio层通常用来缓冲数据。

进一步查看系统活动,我通常使用strace命令,它很好地显示了每个进程如何读取和写入数据。