1

我似乎陷入了僵局。我有 perl 脚本分叉并调用另一个 perl 脚本。这个过程挂在某个地方。

我正在运行程序:Darwin Kernel Version 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 根 1 管道 0x48937dc1254fe937 16384->0x48937dc1254fe727

perl5.12 1768 根 1 管道 0x48937dc1254fe937 16384->0x48937dc1254fe727

perl5.12 1759 根 1 管道 0x48937dc1254fe937 16384 ->0x48937dc1254fe727

perl5.12 1760 根 1 管道 0x48937dc1254fe937 16384->0x48937dc1254fe727

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

4

2 回答 2

0

我能想到的可能有两种:

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

  2. 一个进程正在等待管道上的 EOF,但它永远不会到来。如果管道是在父进程中创建的,然后被子进程继承,则需要确保所有进程都关闭管道的写端,这样读者才会读到EOF。

于 2013-05-10T21:26:27.900 回答
0

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

您将不得不IO::Select在父进程中使用 Perl 模块来继续从子进程读取输出缓冲区,如果子进程的输出大于缓冲区,则将其清空。

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

sysread FILEHANDLE,SCALAR,LENGTH
尝试使用 read(2) 从指定的 FILEHANDLE 将 LENGTH 字节的数据读入变量 SCALAR。它绕过缓冲 IO,因此将其与其他类型的读取、打印、写入、查找、告诉或 eof 混合可能会导致混淆,因为 perlio 或 stdio 层通常缓冲数据。

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

于 2018-06-01T09:57:43.090 回答