如何等待子进程并获取其 return 值
How to wait for a child process and get its return value
我正在尝试在嵌入式 linux 环境中分叉我的 C 应用程序 运行,并获取其 return 值以进行 failure/success 分析。
我查看了类似的问题(例如 this, this, this, this 和其他一些 Q/A..),但仍然无法正常工作。
代码:
static int fork_test(const char *src, const char *dst)
{
int childExitStatus;
pid_t pid;
int status;
DEBUG_PRINT("forking");
pid = fork();
if (pid == 0) { // child
sleep(2);
DEBUG_PRINT("child - exiting");
exit(1);
}
else if (pid < 0) {
return -1;
}
else { // parent
int i;
for (i = 0 ; i < 10 ; i++)
{
pid_t ws = waitpid(pid, &childExitStatus, WNOHANG);
if (-1 == ws)
{
DEBUG_PRINT("parent - failed wait. errno = %d", errno);
return -1;
}
if (0 == ws)
{
DEBUG_PRINT("parent - child is still running");
sleep(1);
continue;
}
}
if (10 == i)
return -1;
DEBUG_PRINT("parent - done waiting");
if (WIFEXITED(childExitStatus)) /* exit code in childExitStatus */
{
DEBUG_PRINT("parent - got status %d", childExitStatus);
status = WEXITSTATUS(childExitStatus); /* zero is normal exit */
if (0 != status)
{
DEBUG_PRINT("parent - picked up bad exit status");
return status;
}
return 0;
}
else
{
DEBUG_PRINT("parent - bad exit route");
return -1;
}
}
}
这提供了这个输出:
forking
parent - child is still running
parent - child is still running
parent - child is still running
child - exiting
parent - failed wait. errno = 10
注意 errno=10 表示 ECHILD。
所以我尝试添加:
...
DEBUG_PRINT("forking");
signal(SIGCHLD,SIG_DFL);
pid = fork();
...
(或 SIG_IGN)没有区别。
我可以成功地为 SIGCHLD 添加一个信号处理程序,并且可以使用 sigwait() 或类似的方法等待信号,而不是子进程,但这似乎是一个糟糕的解决方案..
知道我在这里遗漏了什么吗?
$ uname -mrso
Linux 3.18.20 armv7l GNU/Linux
您的代码很好地测试了 "errors"。好
但是不幸的是,代码没有捕捉到您想要的情况,其中 waitpid()
实际上是 returns child 的 PID。
你可以这样实现:
for (i = 0 ; i < 10 ; i++)
{
pid_t ws = waitpid(pid, &childExitStatus, WNOHANG);
if (-1 == ws)
{
DEBUG_PRINT("parent - failed wait. errno = %d", errno);
return -1;
}
else if (0 == ws)
{
DEBUG_PRINT("parent - child is still running");
sleep(1);
continue;
}
DEBUG_PRINT("parent - successfully waited for child with PID %d", (int) ws);
break;
}
我正在尝试在嵌入式 linux 环境中分叉我的 C 应用程序 运行,并获取其 return 值以进行 failure/success 分析。
我查看了类似的问题(例如 this, this, this, this 和其他一些 Q/A..),但仍然无法正常工作。
代码:
static int fork_test(const char *src, const char *dst)
{
int childExitStatus;
pid_t pid;
int status;
DEBUG_PRINT("forking");
pid = fork();
if (pid == 0) { // child
sleep(2);
DEBUG_PRINT("child - exiting");
exit(1);
}
else if (pid < 0) {
return -1;
}
else { // parent
int i;
for (i = 0 ; i < 10 ; i++)
{
pid_t ws = waitpid(pid, &childExitStatus, WNOHANG);
if (-1 == ws)
{
DEBUG_PRINT("parent - failed wait. errno = %d", errno);
return -1;
}
if (0 == ws)
{
DEBUG_PRINT("parent - child is still running");
sleep(1);
continue;
}
}
if (10 == i)
return -1;
DEBUG_PRINT("parent - done waiting");
if (WIFEXITED(childExitStatus)) /* exit code in childExitStatus */
{
DEBUG_PRINT("parent - got status %d", childExitStatus);
status = WEXITSTATUS(childExitStatus); /* zero is normal exit */
if (0 != status)
{
DEBUG_PRINT("parent - picked up bad exit status");
return status;
}
return 0;
}
else
{
DEBUG_PRINT("parent - bad exit route");
return -1;
}
}
}
这提供了这个输出:
forking
parent - child is still running
parent - child is still running
parent - child is still running
child - exiting
parent - failed wait. errno = 10
注意 errno=10 表示 ECHILD。
所以我尝试添加:
...
DEBUG_PRINT("forking");
signal(SIGCHLD,SIG_DFL);
pid = fork();
...
(或 SIG_IGN)没有区别。 我可以成功地为 SIGCHLD 添加一个信号处理程序,并且可以使用 sigwait() 或类似的方法等待信号,而不是子进程,但这似乎是一个糟糕的解决方案..
知道我在这里遗漏了什么吗?
$ uname -mrso
Linux 3.18.20 armv7l GNU/Linux
您的代码很好地测试了 "errors"。好
但是不幸的是,代码没有捕捉到您想要的情况,其中 waitpid()
实际上是 returns child 的 PID。
你可以这样实现:
for (i = 0 ; i < 10 ; i++)
{
pid_t ws = waitpid(pid, &childExitStatus, WNOHANG);
if (-1 == ws)
{
DEBUG_PRINT("parent - failed wait. errno = %d", errno);
return -1;
}
else if (0 == ws)
{
DEBUG_PRINT("parent - child is still running");
sleep(1);
continue;
}
DEBUG_PRINT("parent - successfully waited for child with PID %d", (int) ws);
break;
}