我正在使用 waitpid 获取子项在更改状态时返回的状态代码。我正在使用:
if (WIFEXITED(code)){
if (WEXITSTATUS(code)==0){
//worked correctly
}
else{
//failed, throw error
}
}
else{
..
}
在底部,我想检查 child 是否在没有终止的情况下改变了状态,并等待它使用循环终止。我该怎么做?
最佳答案
假设您不 ptrace
子进程,您必须使用 WUNTRACED
和 WCONTINUED
标志等待它:
waitpid(pid, &code, WUNTRACED | WCONTINUED);
如果你执行 ptrace
它,WUNTRACED
是不必要的,但由于 ptrace
是完全不同的鱼,我不会去详细介绍。
然后,你可以像这样检查发生了什么:
if (WIFEXITED(code)) {
// process ended normally with exit status WEXITSTATUS(code)
} else if(WIFSIGNALLED(code)) {
// process was terminated by signal WTERMSIG(code)
} else if(WIFSTOPPED(code)) {
// child was stopped by signal WSTOPSIG(code)
} else if(WIFCONTINUED(code)) {
// child was continued
}
要了解其工作方式,您可以尝试一下这段代码:
#include <stddef.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t pid;
pid = fork();
if(pid == -1) {
fputs("fork failed\n", stderr);
} else if(pid == 0) {
int i;
for(i = 0; i < 100; ++i) {
usleep(1000000);
puts("child");
}
} else {
int status;
printf("%d\n", pid);
do {
waitpid(pid, &status, WUNTRACED | WCONTINUED);
printf("exited: %d status: %d\n"
"signalled: %d signal: %d\n"
"stopped: %d signal: %d\n"
"continued: %d\n",
WIFEXITED(status),
WEXITSTATUS(status),
WIFSIGNALED(status),
WTERMSIG(status),
WIFSTOPPED(status),
WSTOPSIG(status),
WIFCONTINUED(status));
} while(!WIFEXITED(status) && !WIFSIGNALED(status));
}
return 0;
}
这会fork,父进程会打印子进程的进程ID,当你给子进程发送信号时,父进程会打印它从waitpid
获取的状态属性(不是所有的其中的一部分自然是有意义的;如果进程停止,WTERMSIG
不会返回任何有意义的信息)。这是我发送子进程 SIGSTOP
、SIGCONT
和 SIGTERM
的 session 的示例输出:
38167
child
child
child
child
exited: 0 status: 19
signalled: 0 signal: 127
stopped: 1 signal: 19
continued: 0
exited: 0 status: 255
signalled: 0 signal: 127
stopped: 0 signal: 255
continued: 1
child
child
child
exited: 0 status: 0
signalled: 1 signal: 15
stopped: 0 signal: 0
continued: 0
关于c++ - 我将如何检查子进程改变状态但不终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28209525/