C fork处理全局变量

时间:2010-01-28 22:13:33

标签: c process global-variables fork

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

#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

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

5 个答案:

答案 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的值。