子进程因错误而终止

Child process terminating on error

我在尝试使用 fork() 和 exit() 函数完成课程作业时遇到问题。问题是我的子进程在应该正确完成时以错误结束。这是我的代码:

int main(int argc, char** argv)
{
    int shmid;
    int *shmptr;
    int N = 10;

    // Create shared memory segment
    if ((shmid = shmget(IPC_PRIVATE, N * N * sizeof(int), 0600)) < 0)
    {
        puts("parent: shmget error");
        return -1;
    }

    // Attach shared memory segment
    if ((shmptr = shmat(shmid, 0, 0)) == (void *) -1)
    {
        puts("parent: shmat error");
        return -1;
    }   

    int ret = fork();
    if (ret == 0) 
    {   
        int status = 0;
        if (wait(&status) == -1)
        {
            puts("parent: Child terminated on error.");
        }
        else 
        {
            printf("parent: status of child: %d\n", status);
        }   
        puts("parent: End parent.");        
    }
    else 
    {
        puts("child: End child.");
        _exit(0);
    }

    exit(0);
}

我总是收到 Child terminated on error 警告。有什么建议吗?

ret 在子进程中应该是 0。在父进程中,ret应该包含子进程的PID.

 int ret = fork();
 if (ret < 0) { perror("fork"); exit(1); } /* handle fork error */
 if (ret == 0)
 {
    puts("child: End child.");
    _exit(0);
 }
 else 
 {
     /* <wait> code goes here */
 }

您的诊断 "Child terminated on error" 是对产生它的条件的错误描述。 wait()函数returns-1在出错的情况下;如果调用进程没有 children 等待或函数被信号中断,就会发生这种情况。

你的情况是前者的原因。当它成功时,fork() 函数 returns 0 在 child 进程中,它 returns 新的 child 的进程 id(一个大于0) 在 parent 进程中。除此之外,这就是 parent 和 child 可以区分哪个是哪个的方式。您正在 child 中调用 wait(),它没有自己的 child 个进程。

请注意,child 调用 _exit() 而不是 exit() 可能存在问题,因为前者会突然停止 child(不刷新打开的文件,除其他事项外)并且还会导致 parent 发出信号(使用 SIGCHILD)。这有时是您想要的,但我不明白为什么在这种情况下您会想要它。

另请注意,wait() 提供的状态编码了所收集进程的多个独立细节,包括但不限于其退出代码。除了通过为此目的提供的各种宏提取感兴趣的部分外,对整个状态做任何事情通常没有用。例如,要获取 child 的退出代码,您应该将状态传递给 WEXITSTATUS() 宏。在实际代码中,测试进程是否正常退出可能是明智的,而不是因为信号而终止。 WEXITED() 宏可以从状态中提取该信息。还有其他编码的信息,以及用于提取它的其他宏。

因此,你可能会用这样的东西做得更好:

    int pid = fork();
    if (pid == 0) 
    {   
        /* child */
        puts("child: End child.\n");
        exit(0);
    }
    else if (pid > 0)
    {
        /* parent */
        int status = 0;
        if (wait(&status) == -1)
        {
            puts("parent: failed to wait.\n");
        }
        else 
        {
            printf("parent: child's exit code: %d\n", WEXITSTATUS(status));
        }   
        puts("parent: End parent.\n");        
    }
    else 
    {
        /* parent; error */
        puts("failed to fork.\n");
    }