2017-05-06 2 views
1

Actuellement j'apprends des threads POSIX sous Linux. L'exemple suivant compte combien de 3 (int) il y a dans un tableau d'entiers, ce qui renvoie une réponse correcte sur CentOS 6.5 mais une mauvaise sur macOS 10.12.4.pthread mutex ne fonctionne pas correctement sur 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; 
} 

La réponse devrait être 64 * 1024 * 1024/2 = 67108864/2 = 33554432. Mais la réponse sur macOS n'est jamais correcte. Je compile le code avec les options suivantes:

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

J'ai essayé de résoudre le problème suivant this link. Cependant, j'ai toujours une mauvaise réponse après avoir initialisé pthread mutex. Ai-je manqué quelque chose? PS: J'ai essayé soit pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ou pthread_mutex_init(&mutex, NULL) mais le programme s'exécutant sur macOS renvoie toujours une mauvaise réponse.

Avancé merci!

+0

La boucle 'for' de' pthread_join' commence à '1' au lieu de' 0'. – mch

+0

Avez-vous obtenu la valeur correcte si vous appelez la fonction sans 'pthread_create'? Je n'obtiens pas votre valeur attendue: http://ideone.com/z3Ne2a – mch

Répondre

2

La ligne count = 0; avant les pthread_create ensembles count à 0, afin de réinitialiser la valeur de count alors que les fils incrémenter. Retirez cette ligne. Il a probablement fonctionné sur d'autres systèmes, lorsque le thread principal termine le pthread_create avant que les threads commencent à compter.

je l'ai déjà mentionné dans les commentaires:

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

devrait être

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

sinon vous n'attendront pas le premier fil à faire.

+0

Merci! Après avoir supprimé la ligne 'count = 0;' et mis 't = 0' dans la boucle pthread_join, le résultat est finalement correct. Cependant, j'ai une autre question: pourquoi 'pthread_create' définit-il automatiquement' count' à '0'? Ni la fonction 'pthread_create' ni' count3s_thread' n'a l'instruction qui peut mettre 'count' à' 0'. – Tau

+0

'count' est une variable globale, qui est' 0' initialisée. – mch

+0

Oh, j'ai juste oublié que les variables globales en C seront automatiquement initialisées à '0'. En tout cas, merci de m'avoir tant dit. – Tau