我不理解这个程序的输出:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
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
有人可以告诉我应该如何处理这个问题,以便完全理解为什么我会得到这个输出?
答案 0 :(得分:25)
Fork将制作该过程的副本。该过程的独立副本。因此,如果一个全局变量在您分叉时包含3,那么该过程的每个副本都会获得它们自己的3.如果它们被修改,它们的修改是完全独立的。
答案 1 :(得分:16)
将您的代码更改为此,输出应该更有意义:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int i = 0;
int main()
{
while (i < 3)
{
fork();
printf("pid = %d, i = %d\n", getpid(), i);
++i;
}
return 0;
}
答案 2 :(得分:5)
fork()时,会在当前状态下创建当前进程的完整副本。这意味着您的初始进程将创建三个处于while循环中间的新进程,其中i
分别为0,1和2。它还会打印自己的i
。
每个孩子都会通过打印出fork()
初始i
值,递增和循环来继续i
调用的循环。这意味着孩子0将打印0,1和2,并产生两个新孩子,其“初始”值为i
1和2.儿童1将打印1和2并再生成一个孩子, “{1}}的”初始“值为2.儿童2将打印2并离开循环。
如果你继续这个推理,你会得出结论,总共有两个0,四个1和八个2将被打印。但是,由于执行顺序取决于操作系统如何安排并发进程,因此无法保证打印顺序。
答案 3 :(得分:3)
如果要在进程内创建并发编程的线程,请尝试使用pthreads。你想要的函数是pthread_create和pthread_join,以便稍后整理。
这样的事情:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
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;
}
但也许不是,取决于你的实际需要。
答案 4 :(得分:2)
就像......
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',它跟踪它,它的值只是分叉过程中i的值。