是否有wait()系统调用的一个版本设置超时?

有没有办法使用wait()系统调用超时,除了使用忙待或忙碌睡眠循环?

我有一个父进程,它是fork本身, exec是一个子可执行文件。 然后等待孩子完成,通过任何适当的方式抓取其输出,并进行进一步的处理。 如果这个过程在一定的时间内没有完成,它就会假定它的执行超时,并且做了其他的事情。 不幸的是,鉴于问题的性质,这个超时检测是必要的。

Solutions Collecting From Web of "是否有wait()系统调用的一个版本设置超时?"

没有等待电话超时。

你可以做的是安装一个信号处理程序,为SIGCHLD设置一个标志,并使用select()来实现超时。 select()会被一个信号中断。

 static volatile int punt; static void sig_handler(int sig) { punt = 1; } ... struct timeval timeout = {10,0}; int rc; signal(SIGCHLD, sig_handler); fork/exec stuff //select will get interrupted by a signal rc = select(0, NULL,NULL,NULL, &tv); if (rc == 0) { // timed out } else if (punt) { //child terminated } 

如果你还需要处理其他信号,那么需要更多的逻辑

您可以使用waitpidWNOHANG选项一起使用并进行睡眠。

 while(waitpid(pid, &status, WNOHANG) == 0) { sleep(1); } 

但是,这将是一个积极的睡眠。 但是我没有看到使用wait类型的功能的其他方式。

在linux上,你也可以使用signalfd来解决这个问题。 signalfd实质上是接收一组信号并创建一个你可以读取的fd; 你读的每个块对应于已经发射的信号。 (你应该用sigprocmask来阻塞这些信号,以便它们不被实际发送。)

signalfd的优点是你可以使用fd和selectpollepoll ,所有这些都允许超时,所有这些都允许你等待其他事情。

一个注意:如果相同的信号在读取相应的struct signalfd_siginfo之前触发两次,则只会收到一个指示。 所以当你得到一个SIGCHLD指示时,你需要重复waitpid(-1, &status, &WNOHANG) ,直到它返回-1。

在FreeBSD上,你可以直接使用kqueueEVFILT_PROC类型来获得相同的效果。 (你也可以对一个SIGCHLD事件进行kqueue,但是EVFILT_PROC可以让你通过子pid来指定事件,而不是全局为所有的孩子。)这也应该可以在Mac OS X上运行,但我从来没有尝试过。