我开始在linux和windows上使用socketpairs,以便在两个平台上捕获子进程的输出。我这样做是通过将STD *复制到socketpair中的一个套接字上(我在perl中使用Win32 :: SocketPair,用于windows上的socketpair)。我这样做的主要原因是读取不会阻塞输出文件句柄。
我遇到的问题是kill(0,...)在Windows上不起作用,所以我需要另一种方法来检测进程为down。我查看了SO_KEEPALIVE,但这似乎不适用于socketpairs ...我使用setsockopt(...)然后getsockopt(...)并且在调用setsockopt()之前和之后关闭了SO_KEEPALIVE选项。 / p>
然后我开始研究套接字上的事件的轮询。 POLLHUP活动看起来很有希望,但我不确定它们是否会像这样使用。
我正在寻求自动化交互式程序(不,我不能使用Except,因为它在Windows平台上不起作用......除非你找到了一个吗?)。我一直在Windows上测试“猫”(我安装了cat.exe)。到目前为止它看起来很好,但有两个问题:
我可能会做一些非常愚蠢的事,但任何建议/帮助都会受到赞赏。
更新:我开始使用waitpid($ pid,WNOHANG)来检测“仍在运行”状态,这有助于因为看起来该过程总是在读完所有内容后死亡。如果pid仍在运行,waitpid返回0。然而,它不是一个EOF,它总比没有好,但我还在寻找其他输入。这显然不太理想。
UPDATE2:这个Q / A有助于我的问题的EOF部分,不完美,但更好: How epoll detect clientside close in Python?
答案 0 :(得分:1)
如果它在WIN32环境中受支持,并且您的进程正在生成子进程,您可以尝试设置信号处理程序以从父进程中的生成进程捕获SIGCHLD信号......类似于:
$ SIG {CHLD} = sub { 打印“从儿童过程中抓住sigchld”; };
这应该告诉你是否退出了其中一个子流程。
答案 1 :(得分:0)
在Linux中,您可以将套接字设置为非阻塞(至少为5.8):
$socket->blocking(0); # or (*SOCKET)->blocking(0);
这在Windows上不起作用(好吧,也许在5.10中也可以),但你可以使用4-arg select调用来查看套接字上是否有输入,然后再尝试读取它(在Windows中, 4-arg select仅适用于sockethandles,而不适用于文件句柄或管道。)
如果您仍需要判断Windows进程(具有已知PID)是否处于活动状态,请检查 Win32::Process::Open method,它将尝试打开Windows进程的句柄并在失败时返回零。
<小时/>
编辑:之前我没有注意到你说套接字来自子进程。在这种情况下,您只需致电
waitpid $pid, WNOHANG; # and use POSIX ':sys_wait_h'
随时。当waitpid
没有返回-1时,您知道该过程已经死亡。