2016-11-12 36 views
2

我的程序所需的功能:
使用命令行用户输入NMN是将要创建的新线程的数量,并且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

+0

应当保护并发读/写访问变量(此处为'A')。例如通过使用互斥锁。 – alk

+0

OT:这个强制转换'(pthread_t *)'在C中没用。或者你应该使用C++编译器吗? – alk

+0

关于使用互斥锁:http://stackoverflow.com/q/34524/694576 – alk

回答

3

问题是,您正在创建多个线程,并行尝试修改您的静态全局变量在同一时间,没有任何形式的保护。

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

您可以用互斥解决这个问题,有其声明:

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; 
} 
+0

*至少应调用* lock和* unlock来调用失败。 – alk

+0

一个建议:在Thread()中为什么我们需要for循环?我们可以做A + = n。 – MayurK

+0

根本不需要,我想他只是在玩代码作为例子。 – maki

相关问题