繁体   English   中英

是否存在设置超时的wait()系统调用版本?

[英]Is there a version of the wait() system call that sets a timeout?

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

我有一个父进程,它自己forkexec一个子可执行文件。 然后它等待孩子完成,通过适当的方式抓取其输出,并执行进一步处理。 如果进程未在一段时间内完成,则假定其执行超时,并执行其他操作。 不幸的是,考虑到问题的性质,这种超时检测是必要的。

没有等待超时的等待呼叫。

你可以做的是安装一个信号处理程序,为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, &timeout ); 
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的优点是你可以使用带有selectpollepoll的fd,所有这些都允许超时,所有这些都允许你等待其他事情。

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

在FreeBSD上,你可以使用kqueueEVFILT_PROC类型的kevent直接实现相同的效果。 (您也可以使用SIGCHLD事件,但EVFILT_PROC允许您通过子pid指定事件而不是全局子项。)这也适用于Mac OS X,但我从未尝试过。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM