【问题标题】:Obtain this exit status of a child process and from the parent process and print it in the parent.从父进程获取子进程的退出状态,并在父进程中打印。
【发布时间】:2017-04-02 07:29:53
【问题描述】:

我正在探索 c 中的流程。我想以某种方式更新以下程序,孩子以退出状态(例如 10)终止。从父进程中获取这个退出状态并打印在父进程中。我尝试了以下方式,但是从父母那里得到的状态是错误的。我哪里出错了?请帮我解决这个问题。提前致谢。

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
    int pid;
    int ppid;
    int status;
    pid=vfork();
    pid_t return_pid = waitpid(pid, &status, WNOHANG);
    //printf("%d\n", pid); --> value = 0

    if (pid < 0) {
        printf("\n Error ");
        exit(1);
    } else if (pid==0) {
        printf("\n Hello I am the child process\n");
        printf("\n My pid is:  %d\n", getpid());
        printf("\n My parent pid is:  %d\n", getppid());
        printf("\n My return_pid is:  %d\n", return_pid);
        printf("_______________________________________\n");
        int es = WEXITSTATUS(status);
        printf ("\n Child exit status:  %d\n", es);
        status = es;
        exit(0);
    } else {
        printf("The child has terminated!\n");
        printf("_______________________________________\n");
        printf("\n Hello I am the parent process\n");
        printf("\n My actual pid is %d\n" , getpid());
        printf("\n My parent pid is:  %d\n", getppid());
        printf("\n My return_pid is:  %d\n", return_pid);
        printf("_______________________________________\n");
        printf ("\n Child's Exit staus from parent:  %d\n", status);
        exit(1);
    }
}

【问题讨论】:

  • 您应该只在 parent 进程中等待子进程。并且记得检查 waitpidWNOHANG 实际返回的状态。
  • 另外,来自the POSIX secification of vfork:“如果vfork()创建的进程修改任何数据而不是变量,则行为未定义pid_t 类型的用于存储来自 vfork()、... 的返回值,或在成功调用 _exit() 或其中一个 exec 之前调用 任何其他函数函数族”。由于您在子进程中修改变量并调用“其他函数”,因此您有未定义的行为
  • 请注意vfork() 不是POSIX 2008 的一部分。它是在 POSIX 的早期版本中定义的,用于向后兼容 SUS(单一 Unix 规范)和 SVID(系统 V 接口定义)。由于对其使用的限制,通常最简单的方法是假装它不存在而不使用它。有人说它使 fork/exec 过程更加有效。您还可以查看posix_spawn() 了解另一种控制子进程的方法。
  • 哦,好的。那么我如何才能在父母中获得孩子的退出状态?
  • 你的孩子的退出状态将为0,除非它被信号杀死,因为你的孩子无条件地exit(0);。您可以使用wait()waitpid() 找到它——忽略WNOHANG 选项;你想挂断电话,直到孩子死去。你的代码结构是……不寻常的,容我们说。只有父母需要等待。

标签: c process


【解决方案1】:

此代码使用fork() 而不是vfork(),所做的事情接近您所追求的。你想等孩子死——不要使用“如果孩子还没有死,不要等孩子死”的选项。最好只在父母那里等待。这段代码有时也会用中断信号杀死孩子——主要是为了让你可以看到退出状态是如何编码的。

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    pid_t pid = fork();

    if (pid < 0)
    {
        perror("fork()");
        exit(1);
    }
    else if (pid == 0)
    {
        printf("Hello I am the child process\n");
        printf("My pid is:  %d\n", (int)getpid());
        printf("My parent pid is:  %d\n", (int)getppid());
        int status = getpid() % 256;
        printf("I am about to exit with status 0x%.2X (%d)\n", status, status);
        printf("_______________________________________\n");
        exit(status);
    }
    else
    {
        int status;
        if (pid % 10 == 0)
            kill(pid, SIGINT);
        pid_t return_pid = waitpid(pid, &status, 0);
        printf("The child has terminated!\n");
        printf("Hello I am the parent process\n");
        printf("My actual pid is %d\n", (int)getpid());
        printf("My parent pid is:  %d\n", (int)getppid());
        printf("My return_pid is:  %d\n", (int)return_pid);
        printf("Child's raw exit status:  0x%.4X (%d)\n", status, status);
        if (WIFEXITED(status))
            printf("Child's exit status: 0x%.2X (%d)\n",
                   WEXITSTATUS(status), WEXITSTATUS(status));
        if (WIFSIGNALED(status))
            printf("Child exited because of signal %d\n", WTERMSIG(status));
        printf("_______________________________________\n");
    }
    return 0;
}

示例输出:

正常运行:

Hello I am the child process
My pid is:  40377
My parent pid is:  40376
I am about to exit with status 0xB9 (185)
_______________________________________
The child has terminated!
Hello I am the parent process
My actual pid is 40376
My parent pid is:  847
My return_pid is:  40377
Child's raw exit status:  0xB900 (47360)
Child's exit status: 0xB9 (185)
_______________________________________

信号运行:

The child has terminated!
Hello I am the parent process
My actual pid is 40379
My parent pid is:  847
My return_pid is:  40380
Child's raw exit status:  0x0002 (2)
Child exited because of signal 2
_______________________________________

【讨论】:

  • 非常感谢乔纳森!
猜你喜欢
  • 2016-05-09
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
相关资源
最近更新 更多