2017-05-06 48 views
1

目前我正在學習Linux上的POSIX線程。以下示例計算整數數組中有多少個3(int),它在CentOS 6.5上返回正確答案,但在macOS 10.12.4上返回錯誤答案。pthread互斥鎖在macOS上無法正常工作

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

#define thread_num 16 
#define MB 1024 * 1024 
int *array; 
int length; //array length 
int count; 
int t; //number of thread 
void *count3s_thread(void* id); 

pthread_mutex_t myMutex;//create a mutex 

int main() 
{ 
    //initialize mutex 
    if (pthread_mutex_init(&myMutex, NULL) != 0) 
     printf("Mutex init failed!\n"); 
    int i; 
    int tid[thread_num]; 
    pthread_t threads[thread_num]; 
    length = 64 * MB; 
    array = malloc(length * 4); 

    //initialize the array 
    //when i is an odd number, array[i] = 4 
    //when i is an even number, array[i] = 3 
    for (i = 0; i < length; i++) 
     array[i] = i % 2 ? 4 : 3; 

    for (t = 0; t < thread_num; t++) 
    { 
     count = 0; 
     tid[t]=t; 
     int err = pthread_create(&(threads[t]), NULL, count3s_thread,&(tid[t])); 
     if (err) 
     { 
      printf("create thread error!\n"); 
      return 0;   
     } 
    } 
    for (t = 1; t < thread_num; t++) 
     pthread_join(threads[t], NULL); 
    printf("Total count= %d \n",count); 

    pthread_mutex_destroy(&myMutex); 

    return 0; 
} 

void *count3s_thread(void* id) 
{ 
    //printf("id from count3s_thread = %d\n", *(int *)id); 
    int length_per_thread = length/thread_num; //length of every thread 
    int start = *(int *)id * length_per_thread; 
    int i; 
    for (i = start; i < start + length_per_thread; i++) 
    { 
     if (array[i] == 3) 
     { 
      pthread_mutex_lock(&myMutex); 
      count++; 
      pthread_mutex_unlock(&myMutex); 
     } 
    } 
    return NULL; 
} 

答案應該是64 * 1024 * 1024/2 = 67,108,864/2 = 33,554,432。但是macOS上的答案是不對的。我編譯下列選項代碼:

gcc mutex-demo.c -lpthread -o mutex-demo 

我試圖解決這個問題下面this link。但是,我仍然得到了初始化pthread互斥鎖的錯誤答案。我錯過了什麼?

PS:我試過pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_init(&mutex, NULL),但運行在macOS上的程序仍然返回錯誤答案。

高級謝謝!

+0

pthread_join的'for'循環從'1'開始,而不是'0'。 – mch

+0

如果您在沒有'pthread_create'的情況下調用函數,您是否得到了正確的值?我沒有得到您的預期價值:http://ideone.com/z3Ne2a – mch

回答

2

pthread_createcount0前行count = 0;,讓你重置count值,而線程遞增它們。刪除這一行。當主線程在線程開始計數之前完成pthread_create時,它可能在其他系統上工作。

我已經在評論中提到:

for (t = 1; t < thread_num; t++) 
    pthread_join(threads[t], NULL); 

應該

for (t = 0; t < thread_num; t++) 
    //^
    pthread_join(threads[t], NULL); 

否則你不會等待要完成的第一個線程。

+0

謝謝!在pthread_join循環中刪除行'count = 0;'並設置't = 0'後,結果最終正確。但是,我還有一個問題:爲什麼'pthread_create'自動將'count'設置爲'0'?函數'pthread_create'和'count3s_thread'都沒有可以將'count'設置爲'0'的語句。 – Tau

+0

'count'是一個全局變量,它是'0'初始化的。 – mch

+0

呵呵,我只是忘記C中的全局變量會自動初始化爲'0'。無論如何,謝謝你告訴我這麼多。 – Tau