我有以下程序,只是为了测试我是否理解了分叉和共享内存。总之,它创建共享内存、分叉、分叉、分叉,并在每个分叉中写入数据并退出。
#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)
。尤其是第三次 fork 之后的进程,我认为应该会到达exit(0)
与第二次 fork 相同的对 的调用。
但是,当我在第三个 fork 块内(即 after c3==0
)添加对 exit 的明确调用时,它就会按预期执行。
当我写这篇文章时,我突然想到了一个关于为什么会发生这种情况的猜测:是不是因为第二个子进程在第三个子进程之前到达退出,并且因为它退出了,所以从第四个子进程到父进程的链接就断了?
您当前尝试
wait
对原始父进程中的三个进程执行此操作,但该进程只有一个子进程,因此只有第一个进程wait
成功。在打印结果之前,无法保证其他进程已准备好写入共享内存。为了确保孩子都完成任务,每个父母都应该等待其孩子。
例子: