为何在if内修改x为10后,二次fork的进程仍输出33?
问题分析:fork()与变量作用域、进程内存隔离的问题
示例代码
int main(int argc, char *argv[ ]){ int x = 33; if(!fork()){ int x = 10; printf("%d\n", x); } fork(); printf("%d\n", x); return 0; }
问题描述
我原本以为第一个子进程在if代码块里把x改成10后,这个值会保留到第二次fork()执行时,所以这个子进程及其后续创建的子进程都会输出10,预期输出是:33 33 10 10 10。但实际运行结果是,即便在if里修改了x的值,后续子进程依然用x的原始值33,第二次fork后的两个进程都输出33,实际输出为:33 33 10 33 33。请问这是为什么?(我认为换行符\n和这个问题无关)
原因解析
核心原因有两个:变量作用域和fork()的进程内存隔离特性
变量作用域问题
if代码块里的int x = 10;是重新定义了一个局部变量,它和外层的int x = 33;是两个完全独立的变量,只是名字相同。这个局部x仅在if代码块内部有效,一旦跳出if块,后续代码依然使用外层定义的x(值为33)。哪怕是在第一个子进程中,出了if块之后,fork()和printf("%d\n", x);调用的都是外层的x,值还是33。fork()的进程内存隔离
fork()创建的子进程会复制父进程的内存空间,是独立的写时复制副本,父子进程的变量互不影响。不过这里根本轮不到内存隔离发挥作用——因为第一个子进程里,if块内的x是局部变量,出了块就失效了,子进程后续代码用的还是原来的x=33,所以第二次fork出来的子进程自然也继承这个值。
简单总结:你在if里不是修改了原来的x,而是新建了一个同名的局部x,出了if就失效了,所以后续代码始终使用最初的33。
内容的提问来源于stack exchange,提问作者Mike Balts
相关产品推荐
相关产品推荐

