C fork处理全局变量

我不理解这个程序的输出:

#include  #include  #include  int i = 0; int main() { while(i<3) { fork(); printf("%d\n",i); ++i; } } 

输出是:

 0 1 2 2 1 2 0 1 2 2 2 1 2 2 

可以请有人告诉我如何解决这个问题,以便完全理解为什么我得到这个输出?

Fork将制作该过程的副本。 该过程的独立副本。 因此,如果一个全局变量在您分叉时包含3,那么该过程的每个副本都会获得它们自己的3.如果它们修改,它们的修改是完全独立的。

将代码更改为此,输出应该更有意义:

 #include  #include  #include  int i = 0; int main() { while (i < 3) { fork(); printf("pid = %d, i = %d\n", getpid(), i); ++i; } return 0; } 

fork()时,将在当前状态下创建当前进程的完整副本。 这意味着您的初始进程将创建三个处于while循环中间的新进程,其中i分别为0,1和2。 它还将打印自己的i值。

它的每个子节点都会通过打印出它的初始i值,递增和循环来从fork()调用继续循环。 这意味着孩子0将打印0,1和2,并产生两个新孩子,其“初始”值为i 1和2.孩子1将打印1和2并再生成一个孩子,具有“初始”值儿童2将打印2并离开循环。

如果你继续这个推理,你会得出结论,总共有两个0,四个1和八个2将被打印。 但是,由于执行顺序取决于操作系统如何安排并发进程,因此您无法保证打印的顺序。

如果要在进程内创建并发编程的线程,请尝试使用pthreads。 你想要的function是pthread_create和pthread_join以便稍后整理。

像这样的东西:

 #include  #include  #include  #include  int i = 0; void *threadFunc(void *arg) { printf("%d\n",i); } int main() { int j = 0; int returnValue = 0; pthread_t* myThread = (pthread_t*) calloc(3, sizeof(pthread_t));; while(i < 3) { returnValue = pthread_create(&myThread[i], NULL, threadFunc, NULL); printf("main thread: %d\n",i); i++; } for(j = 0; j < 3; j++) { pthread_join(myThread[j], NULL); } return 0; } 

但也许不是,取决于您的实际需求。

这有点像……

  1 (main) instance, i = 0(unforked) fork() > 2 instances, with i's = 0(forked), and 0(forked) 0 output from main instance, increments its i, 2 instances with i = 1u, 0f main instance forks, there's 3 instances with i's 1f, 1f, 0f 1 output from main instance, increments its i, 3 instances with i = 2u, 1f, 0f main instance forks, there's 4 instances with i's 2f, 2f, 1f, 0f 2 output from main instance, increments its i, 4 instances with i = 3u, 2f, 1f, 0f main instance then dies, 3 instances with i = 2f, 1f, 0f 2 output from next instance, increments its i, 3 instances with i = 3u, 1f, 0f next instance then dies, 2 instances with i = 1f, 0f 1 output from next instance, increments its i to 2, 2 instances with i = 2u, 0f 

…等等

但是,进程输出的顺序是不确定的,因此您每次都可能看不到完全相同的输出,即使您这样做也不是您可以保证的。

正如其他人所说的那样,每个进程都有自己的全局’i’,它跟踪它,它的值只是分叉过程中的分叉过程的值。