套接字对,perl,KEEPALIVE和轮询

时间:2009-12-15 15:48:13

标签: windows perl sockets automation

我开始在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)。到目前为止它看起来很好,但有两个问题:

  • 无法检测进程是否死亡(kill(0,...)无效)
  • 无法从子进程中检测到EOF(sysread似乎始终返回undef或字节读取,永远不会为0,即使在我关闭($ sock,1)之后)

我可能会做一些非常愚蠢的事,但任何建议/帮助都会受到赞赏。

更新:我开始使用waitpid($ pid,WNOHANG)来检测“仍在运行”状态,这有助于因为看起来该过程总是在读完所有内容后死亡。如果pid仍在运行,waitpid返回0。然而,它不是一个EOF,它总比没有好,但我还在寻找其他输入。这显然不太理想。

UPDATE2:这个Q / A有助于我的问题的EOF部分,不完美,但更好: How epoll detect clientside close in Python?

2 个答案:

答案 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,它将尝试打开W​​indows进程的句柄并在失败时返回零。

<小时/>

编辑:之前我没有注意到你说套接字来自子进程。在这种情况下,您只需致电

waitpid $pid, WNOHANG;   # and    use POSIX ':sys_wait_h'

随时。当waitpid没有返回-1时,您知道该过程已经死亡。