我在努力理解以下c程序的输出
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void) {
int i = 1;
pid_t childId = fork();
pid_t pid = getpid();
if (childId == -1) {
perror("fork() failed");
} else if (childId == 0) {
printf("child PID: %d\n", pid);
int *j = NULL;
j = &i;
(*j)++;
printf("value i in child: %d\t@adresse: %p\n",i ,&i);
} else {
pid_t pid = getpid();
printf("parent PID: %d\nwait for child\n", pid);
waitpid(childId, NULL, 0);
printf("value i in parent: %d\t@adresse: %p\n",i ,&i);
}
return 0;
}
输出:
parent PID: 10656
wait for child
child PID: 10657
value i in child: 2 @address: 0x7fff93b720c0
value i in parent: 1 @address: 0x7fff93b720c0
子线程使存储在给定地址中的'i'递增。等待子级之后,父线程继续执行并在相同的地址但以初始值打印“ i”。这也不应该是2吗?
答案 0 :(得分:1)
用户应用程序使用virtual memory。如果您使用fork()
,则创建一个单独的进程,该进程使用与父进程具有相同地址的虚拟内存。
因此,两个进程都使用具有相同地址的虚拟地址空间(如您的printfs所示),但是它们可能在单独的物理内存上运行。
来自Wikipedia(重点是我的)的更详细的解释:
fork操作为孩子创建一个单独的地址空间。的 子进程具有所有内存段的精确副本 父进程。在跟随虚拟内存的现代UNIX变体中 在SunOS-4.0的模型中,实现了写时复制语义,并且 物理内存不需要实际复制。相反,虚拟内存 两个进程中的页面可能引用相同的物理内存页面 直到其中一个人写到这样的页面:然后将其复制。