Process 监视进程是否已在C中终止 导言
我正在用C编写一个监控程序,它执行Process 监视进程是否已在C中终止 导言,process,monitoring,c,fork,Process,Monitoring,C,Fork,我正在用C编写一个监控程序,它执行fork()和exec()循环。但是,我需要检查子进程是否在不阻塞主进程(即监控程序)的情况下终止。大概是这样的: 主要过程 我尝试过的 考虑到我有孩子,我尝试了以下方法: 用信号0发送kill呼叫并检查errno: if(kill(child|pid,0)=-1 | | errno==ESRCH),我认为这不是跟踪子进程状态的好方法,因为它不安全。此外,它并没有起作用,或者至少看起来是这样 使用stat(2)检查proc/child\u pid是否存在。在这
fork()
和exec()
循环。但是,我需要检查子进程是否在不阻塞主进程(即监控程序)的情况下终止。大概是这样的:
主要过程
我尝试过的
考虑到我有孩子,我尝试了以下方法:
- 用
信号0发送
呼叫并检查kill
:errno
,我认为这不是跟踪子进程状态的好方法,因为它不安全。此外,它并没有起作用,或者至少看起来是这样if(kill(child|pid,0)=-1 | | errno==ESRCH)
- 使用
检查stat(2)
是否存在。在这种情况下,上面所有的否定参数都是正确的,而且这种方法速度较慢proc/child\u pid
。不幸的是,它阻碍了主要进程waitpid(2)
有没有其他办法获得这类信息?或者可能我在我已经尝试过的解决方案中遗漏了什么?如果您将
WNOHANG
传递到waitpid
,它应该不会阻塞
if(waitpid(child_pid, &status, WNOHANG) != 0) {
// child process has finished
foo();
} else {
// child process still running
bar();
}
当进程终止时,您可以设置父进程以获取和处理
SIGCHLD
信号,请参阅;信号处理程序只能调用异步信号安全函数,或在处理程序外部(例如,在主事件循环中…)或某些文件描述符(例如,管道或其他)设置测试的volatile sigamatic\u t
标志。您也可以使用Linux特有的signalfd
然后您可以使用一些等待功能,例如(如果您不想阻止,可以使用WNOHANG
)或等待进程并获取其状态等
阅读更多。关于这些问题有几个章节。< P>如果你希望你的进程不阻塞,或者你还有其他文件描述符来检查,那么你应该考虑系统调用,如果你正在为Linux编写。
此系统调用返回一个特殊的文件描述符,您可以在
select()
、poll()
和epoll()
系统调用中使用该描述符。如果设置正确,退出的子进程将导致内核使特殊文件描述符可读。从特殊文件描述符中读取将为您提供一个填充结构,其中包含有关子进程退出状态的信息。Basile Starynkevitch的回答涵盖了最常见的情况
如果您有更多不寻常的情况,使用管道有时会很有用。在创建子进程之前,请使用pipe
系统调用创建管道。创建子进程后,关闭父进程中管道的写入端。从管道读取数据将一直阻塞,直到子节点终止
这与waitpid
的不同之处在于:
- 从管道读取将等待子级及其所有子级终止(除非其中一些子级在此之前关闭文件描述符)
- 可以从同一文件描述符读取多个进程,从而导致所有进程等待同一个进程(或多个进程)终止
- 您不限于等待孩子终止。使用此方法,您还可以等待父级或同级终止
- 通过使用close-on-exec,您可以等待进程终止或成功执行
系统调用execve
- 您可以在管道上使用
或select
系统调用以及其他文件描述符poll
kill
ing一个带有任何信号的child\u pid
是完全安全的竞争条件,只要你还没有收获(=等待)子进程,但是用零杀死不是确定进程是否死亡的好方法。重复杀死你的僵尸孩子是完全可以接受的,你不会得到任何ESRCH错误,直到你等待,这时比赛条件来了。
if(waitpid(child_pid, &status, WNOHANG) != 0) {
// child process has finished
foo();
} else {
// child process still running
bar();
}