3

Here is my code:

#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;
}

the output like that:

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

The address of global variable t is same, does all threads operate the same variable t? I expect the val was "0, 1, 2, 3, 4, 5, ...", how should I do?

4

3 回答 3

4

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

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

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;
}
于 2012-09-13T10:12:31.243 回答
3

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

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

于 2012-09-13T10:18:09.253 回答
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.

于 2012-09-13T10:26:45.657 回答