Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是否存在设置超时的wait()系统调用版本?_C_Linux_Multiprocessing_Wait - Fatal编程技术网

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

C 是否存在设置超时的wait()系统调用版本?,c,linux,multiprocessing,wait,C,Linux,Multiprocessing,Wait,除了使用忙等待或忙睡眠循环外,还有什么方法可以使用带超时的wait()系统调用 我有一个父进程,forks本身和execs子可执行文件。然后,它等待子进程完成,以任何适当的方式获取其输出,并执行进一步的处理。如果进程没有在某个时间段内完成,它将假定其执行超时,并执行其他操作。不幸的是,鉴于问题的性质,此超时检测是必要的。您可以将waitpid与WNOHANG选项和睡眠一起使用 while(waitpid(pid, &status, WNOHANG) == 0) { sleep(1

除了使用忙等待或忙睡眠循环外,还有什么方法可以使用带超时的
wait()
系统调用


我有一个父进程,
fork
s本身和
exec
s子可执行文件。然后,它等待子进程完成,以任何适当的方式获取其输出,并执行进一步的处理。如果进程没有在某个时间段内完成,它将假定其执行超时,并执行其他操作。不幸的是,鉴于问题的性质,此超时检测是必要的。

您可以将
waitpid
WNOHANG
选项和睡眠一起使用

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

但这将是一个积极的睡眠。但是,我认为没有其他方法可以使用
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, &timeout ); 
if (rc == 0) {
// timed out
} else if (punt) {
    //child terminated
}

如果您还需要处理其他信号,则需要更多的逻辑。尽管在linux上,您也可以使用
signalfd
解决此问题
signalfd
基本上接收一组信号并创建一个您可以读取的fd;您读取的每个块对应一个已触发的信号。(应使用sigprocmask阻止这些信号,以便它们不会实际发送。)

signalfd
的优点是,您可以将fd与
select
poll
epoll
一起使用,所有这些都允许超时,并且所有这些都允许您等待其他事情

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


在FreeBSD上,您可以更直接地使用
kqueue
EVFILT\u PROC
类型的
kevent
来实现相同的效果。(您也可以对SIGCHLD事件进行排队,但EVFILT_PROC允许您通过子pid而不是全局指定所有子项的事件。)这也应该适用于Mac OS X,但我从未尝试过。

介意我们问一下您为什么需要这样的东西吗?(如果有其他选择)可能的重复“除了使用忙碌的等待或忙碌的睡眠循环”,我认为这是一个不优雅的最后手段。“亚历克斯似乎我没有仔细阅读这个问题。但是,我看不到除此之外的其他方法如果您已经安装了轮询循环,那么您最好设置一个signalfd来捕获信号。在示例中,
&tv
实际上应该是
&timeout
?如果没有,应该如何使用
超时