【问题标题】:How to wait for a child process and get its return value如何等待子进程并获取其返回值
【发布时间】:2018-01-01 12:17:31
【问题描述】:

我正在尝试 fork 我的 C 应用程序,在嵌入式 linux 环境中运行,并获取其返回值以进行失败/成功分析。

我查看了类似的问题(例如thisthisthisthis 和其他一些 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;
    }
}
} 

这提供了这个输出:

分叉
父母 - 孩子仍在运行
父母 - 孩子仍在运行
父母 - 孩子仍在运行
孩子 - 退出
父母 - 等待失败。错误号 = 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

【问题讨论】:

    标签: c linux fork waitpid


    【解决方案1】:

    您的代码很好地测试了“错误”。很好。

    但不幸的是,代码未能捕捉到您所追求的情况,waitpid() 实际上返回孩子的 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;
    }
    

    【讨论】:

    • 正确。太多的问答让我发现问题太深了。谢谢
    猜你喜欢
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多