为什么使用线程时我的程序输出总是不同?

时间:2016-11-12 16:06:01

标签: c multithreading pthreads

我的程序所需的功能:
使用命令行用户输入 N M N 是将要创建的新主题的数量, M 是每个主题增加全局变量 A 的数量。

这是我的代码:

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

static int A = 0;

void *Thread(void* x){
        int i;
        int n = *((int*)x);
        for (i = 0; i<n; i++){
                A++;
        }
}

int main(int argc, char* argv[]){
        int i;
        int N = atoi(argv[1]);
        int M = atoi(argv[2]);

        pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t)*N);

        if(!thread){
                printf("No memory\n");
                exit(2);
        }

        for (i = 0; i< N; i++){
                if (pthread_create(&thread[i], NULL, Thread, &M)){
                        printf("Not able to create a thread\n");
                        exit(1);
                }
        }

        for(i = 0; i< N; i++)
                pthread_join(thread[i], NULL);

        printf("A = %d\n", A);

        return 0;
}

问题在于每次运行它都有不同的输出。 Screenshot of my terminal when i run the program multiple times in a row

1 个答案:

答案 0 :(得分:3)

问题在于您正在创建多个线程并行尝试同时修改静态A全局变量,而没有任何保护。

这意味着根据线程的调度,全局变量的变化不会是原子的,从而产生这种效果。

您可以使用互斥锁解决此问题,并将其声明为:

pthread_mutex_t mutex;

使用pthread_mutex_init和pthread_mutex_destroy初始化/释放它。

在线程内部,在执行更改之前保护资源以使用pthread_mutex_lock进行更改,并使用pthread_mutex_unlock释放它。所以代码将会改变如下:

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

static int A = 0;
pthread_mutex_t mutex;


void *Thread(void* x){
        int i;
        int n = *((int*)x);

        pthread_mutex_lock(&mutex);
        A += n;
        pthread_mutex_unlock(&mutex);
}

int main(int argc, char* argv[]){
        int i;
        int N = atoi(argv[1]);
        int M = atoi(argv[2]);

        pthread_mutex_init(&mutex, NULL);
        pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t)*N);

        if(!thread){
                printf("No memory\n");
                exit(2);
        }

        for (i = 0; i< N; i++){
                if (pthread_create(&thread[i], NULL, Thread, &M)){
                        printf("Not able to create a thread\n");
                        exit(1);
                }
        }

        for(i = 0; i< N; i++)
                pthread_join(thread[i], NULL);

        printf("A = %d\n", A);

        pthread_mutex_destroy(&mutex);

        return 0;
}