2017-05-06 9 views
1

현재 Linux에서 POSIX 스레드를 배우고 있습니다. 다음 예제는 CentOS 6.5에서 정답을 반환하는 정수 배열에 얼마나 많은 3 (int)가 있는지 계산하지만 macOS 10.12.4에서는 잘못된 답을 반환합니다.pthread mutex가 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에 대한 대답은 결코 옳지 않습니다. 내가 this link을 다음과 같은 문제를 해결하는 시도

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

: 나는 다음과 같은 옵션을 사용하여 코드를 컴파일합니다. 그러나, 나는 여전히 pthread 뮤텍스를 초기화 한 잘못된 대답을 가지고있다. 내가 뭐 놓친 거 없니?

추 신 : pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 또는 pthread_mutex_init(&mutex, NULL) 중 하나를 시도했지만 macOS에서 실행되는 프로그램이 여전히 잘못된 대답을 반환합니다.

고맙습니다! 스레드가 그들을 증가하면서 count의 값을 다시 있도록

+0

'pthread_join'을위한'for' 루프는'0' 대신'1'에서 시작합니다. – mch

+0

'pthread_create'없이 함수를 호출하면 올바른 값을 얻었습니까? 나는 당신의 기대 값을 얻지 못한다 : http://ideone.com/z3Ne2a – mch

답변

2

count0pthread_create 세트 앞에 선 count = 0;. 이 행을 제거하십시오. 스레드가 계산을 시작하기 전에 주 스레드가 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

고마워! 'count = 0;'라인을 제거하고 pthread_join 루프에서't = 0'을 설정하면 결과는 마침내 맞습니다. 그러나, 또 하나의 질문이 있습니다 : 왜'pthread_create'가'count'를'0'으로 자동 설정합니까? 'pthread_create' 나'count3s_thread' 함수는'count'를'0'으로 설정할 수 없습니다. – Tau

+0

'count'는 전역 변수이며 초기화되는 '0'입니다. – mch

+0

아, C에서 전역 변수가 자동으로 '0'으로 초기화된다는 사실을 잊어 버렸습니다. 어쨌든, 너무 많이 말해 주셔서 감사합니다. – Tau