为何两段含fork()的C代码中变量v的修改结果不同?
为什么fork()后子进程修改变量,父进程看不到变化?
先看你给出的第一段代码:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> int v = 5; int main(){ pid_t piid; piid = fork(); if(piid==0){ v += 15; return 0; } else if(piid >0){ wait(NULL); printf("Final value = %d\n",v); return 0; } }
第一段代码里变量v不变的核心原因
这完全是fork()系统调用的特性导致的:当你调用fork()时,操作系统会创建一个全新的子进程——这个子进程是父进程的完整副本,但拥有完全独立的地址空间。也就是说,子进程里的所有变量(包括全局变量v)都是父进程变量的一份拷贝,二者指向的是不同的内存地址。
- 子进程执行
v +=15时,修改的只是自己地址空间里的那份v拷贝,和父进程的v没有任何关联; - 父进程调用
wait(NULL)只是等待子进程执行完毕,但子进程的修改不会同步回父进程的地址空间,所以最后printf输出的还是初始值5。
第二段代码变量v变化的可能原因
你提到第二段代码里v的值发生了变化,虽然没贴代码,但大概率是以下情况之一:
- 没有创建新进程:比如直接在同一个
main函数里执行v +=15,没有调用fork(),那修改的就是同一个变量,值自然会变成20; - 使用线程而非进程:如果是用
pthread创建线程,线程是共享进程地址空间的,线程里修改v会直接改变同一个内存地址的值,主线程就能看到变化; - 用了进程间通信/共享内存机制:如果第二段代码里用了
shmget、mmap这类共享内存手段,或者通过管道、消息队列传递变量值,父进程就能拿到子进程修改后的v值。
简单来说:进程拥有独立地址空间,修改的是自己的拷贝;同一进程内的代码(或线程)共享地址空间,修改的是同一个变量。
内容的提问来源于stack exchange,提问作者Lucas Urake
相关产品推荐
相关产品推荐

