为什么一个进程在fork时没有到达`exit(0)`?

问题描述 投票:0回答:1

我有以下程序,只是为了测试我是否理解分叉和共享内存。 总而言之,它会创建共享内存,分叉,分叉,分叉,并在每个分叉中写入数据并退出。

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

#include <sys/shm.h>
#include <sys/ipc.h>

int main() {
    
    key_t key = ftok(".", 'x');
    int shmid = shmget(key, sizeof(int)*4, IPC_CREAT | 0666);
    if (shmid < 0) {
        perror("shmget\n");
        return 1;
    }
    int *arr = shmat(shmid, NULL, 0);
    pid_t c1 = fork();
    if (c1==0) {
        pid_t c2 = fork();
        if (c2==0) {
            pid_t c3 = fork();
            if (c3==0) {
                arr[0] = 10;
            } else {
                arr[1] = 11;
            }
            exit(0);
        } else {
            arr[2] = 12;
        }
        exit(0);
    } else {
        arr[3] = 13;
        wait(NULL);
        wait(NULL);
        wait(NULL);

        for (int i=0; i<4; i++) printf("%d ", arr[i]);
        printf("\n");
    }
    exit(0);
}

这会打印

0 11 12 13
,表明由于某种原因,值
10
从未分配给
arr[0]

我预计每个进程都会对

exit(0)
进行一些调用。 特别是第三个分叉之后的那个,我认为应该达到与第二个分叉所达到的相同的对
exit(0)
的调用。

但是,当我在第三个 fork 的块内添加对 exit 的显式调用时(即在

c3==0
之后),它就会按预期执行。

当我写这篇文章时,我突然猜测为什么会发生这种情况:是不是因为第二个子节点在第三个子节点之前到达退出,并且因为它退出,所以从第四个子节点到父节点的链接被破坏了?

c fork shared-memory
1个回答
0
投票

您当前尝试对原始父进程中的三个进程进行

wait
,但它只有一个子进程,因此只有第一次等待成功。在打印结果之前,无法保证其他进程已准备好写入。

为了确保孩子们都完成,每个家长都可以等待自己的孩子。

示例:

pid_t c1 = fork();
if (c1==0) { // child
    pid_t c2 = fork();
    if (c2==0) { // child
        pid_t c3 = fork();
        if (c3==0) { // child
            arr[0] = 10;
        } else {
            arr[1] = 11;
        }
        waitpid(c3, NULL, 0); // waiting for child
        exit(0);
    } else {
        arr[2] = 12;
    }
    waitpid(c2, NULL, 0);    // waiting for child
    exit(0);
} else {
    arr[3] = 13;
    waitpid(c1, NULL, 0);    // waiting for child
    for (int i=0; i<4; i++) printf("%d ", arr[i]);
    printf("\n");
}
© www.soinside.com 2019 - 2024. All rights reserved.