关于多线程编程中全局变量的一些问题

时间:2012-09-13 10:07:50

标签: c multithreading global-variables

这是我的代码:

#include <stdio.h>
#include <unistd.h>

static volatile int t=0;

int main(void){
    int i;
    for (i=0; i<2; i++){
        fork();
        printf("pid:%d: addr:%d val:%d\n", getpid(), &t, t++);
    }
    printf("pid:%d: addr:%d val:%d\n", getpid(), &t, t++);
    return 0;
}
输出就像那样:

pid:16232: addr:134518684 val:0
pid:16233: addr:134518684 val:0
pid:16232: addr:134518684 val:1
pid:16232: addr:134518684 val:2
pid:16234: addr:134518684 val:1
pid:16234: addr:134518684 val:2
pid:16233: addr:134518684 val:1
pid:16233: addr:134518684 val:2
pid:16235: addr:134518684 val:1
pid:16235: addr:134518684 val:2

全局变量t的地址相同,所有线程是否都运行相同的变量t?我希望val是“0,1,2,3,4,5 ......”,我该怎么办?

3 个答案:

答案 0 :(得分:4)

这是一个不同的过程, NOT 产生新的线程。结果是有道理的,因为分叉的进程将获得父进程内存的副本

如果您打算使用分叉,这是一种更标准的方法:

int main ()
{
   int pid;

   pid = fork();

   if (pid == 0) {
      // This will be where the child process executes
   } else if (pid > 0) {
     // This is where the parent process executes
   }
   return 0;
}

答案 1 :(得分:3)

结果是正确的。这是因为,在分叉时,您创建一个获取父进程内存副本的新进程。

您看到的地址是虚拟的,因此,即使它们相同,也并不意味着它们指向相同的物理内存区域。

答案 2 :(得分:3)

由于其他人提到的原因,

fork不会产生您期望的结果。即使它确实产生了一个新线程,你也不会以线程安全的方式递增变量。如果你想生成线程并在每个中增加一个变量,你可以使用pthreads和互斥量,如下所示:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

int t = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* threadFunc(void* param) {
    pthread_mutex_lock(&mutex);
    printf("%d\n", t++);
    pthread_mutex_unlock(&mutex);
}

int main(void){
    int i;
    pthread_t threads[5];
    for (i = 0; i < 5; i++){
        pthread_create(&threads[i], NULL, threadFunc, NULL);
    }

    for (i = 0; i < 5; i++){
        pthread_join(threads[i], NULL);
    }

    pthrad_mutex_destroy(&mutex);
    return 0;
}

所有线程共享父进程的地址空间(t所在的地址空间),因此它们都将增加相同的t