Résultat inattendu du producteur-consommateur OpenMP

Je travaille sur un problème simple producteur-consommateur, en utilisant OpenMP en C.

Mon programme crée 4 fils, dont deux sont des consommateurs et deux des producteurs. Chaque producteur place un personnage dans un tampon et les consommateurs l’impriment simplement.

Mon but est de synchroniser les producteurs / consommateurs afin que chaque producteur produise le prochain caractère dans l’ordre de l’alphabet et que chaque consommateur imprime le prochain caractère dans l’ordre placé dans la mémoire tampon.

Ceci est mon code:

#include  #include  #include  #define SIZE 5 #define NUMITER 26 char buffer[SIZE]; int nextin = 0; int nextout = 0; int count = 0; int empty = 1; int full = 0; int i,j; void put(char item) { buffer[nextin] = item; nextin = (nextin + 1) % SIZE; count++; if (count == SIZE) full = 1; if (count == 1) // buffer was empty empty = 0; } void producer(int tid) { char item; while( i < NUMITER) { #pragma omp critical { item = 'A' + (i % 26); put(item); i++; printf("%d Producing %c ...\n",tid, item); } sleep(1); } } char get() { char item; item = buffer[nextout]; nextout = (nextout + 1) % SIZE; count--; if (count == 0) // buffer is empty empty = 1; if (count == (SIZE-1)) // buffer was full full = 0; return item; } void consumer(int tid) { char item; while(j < NUMITER ) { #pragma omp critical { j++; item = get(); printf("%d ...Consuming %c\n",tid, item); } sleep(1); } } int main() { int tid; i=j=0; #pragma omp parallel firstprivate(i,j) private(tid) num_threads(4) { tid=omp_get_thread_num(); if(tid%2==1) { producer(tid); } else { consumer(tid); } } } 

Et voici la sortie:

 0 Producing A ... 2 Producing B ... 1 ...Consuming A 3 ...Consuming B 1 ...Consuming <---- notice empty 0 Producing C ... 3 ...Consuming <---- notice empty 2 Producing D ... 2 Producing E ... 3 ...Consuming E 0 Producing F ... 1 ...Consuming F 2 Producing G ... 3 ...Consuming G 0 Producing H ... 1 ...Consuming H 3 ...Consuming D 2 Producing I ... 0 Producing J ... 1 ...Consuming J 3 ...Consuming F 2 Producing K ... 0 Producing L ... 1 ...Consuming L 3 ...Consuming H 2 Producing M ... 0 Producing N ... 1 ...Consuming N 3 ...Consuming J 2 Producing O ... 0 Producing P ... 1 ...Consuming P 3 ...Consuming L 2 Producing Q ... 0 Producing R ... 1 ...Consuming R 2 Producing S ... 3 ...Consuming S 0 Producing T ... 1 ...Consuming T 3 ...Consuming P 2 Producing U ... 0 Producing V ... 1 ...Consuming V 2 Producing W ... 3 ...Consuming W 0 Producing X ... 1 ...Consuming X 2 Producing Y ... 3 ...Consuming Y 0 Producing Z ... 1 ...Consuming Z 

Les lignes vides qui n’ont pas imprimé de caractère indiquent que je ne parviens pas à la synchronisation souhaitée. Qu’est-ce que je rate?

Merci d’avance pour toute aide ou idées.

Donc, @Jlghtuse avait raison, il y avait des courses de données et c’était à cause de déclarations erronées des zones critiques.

Vous voyez, j’ai déclaré mes zones critiques:

 void consumer(int tid) { char item; while(j < NUMITER ) { #pragma omp critical { j++; item = get(); printf("%d ...Consuming %c\n",tid, item); } sleep(1); } } 

et

 void producer(int tid) { char item; while( i < NUMITER) { #pragma omp critical { item = 'A' + (i % 26); put(item); i++; printf("%d Producing %c ...\n",tid, item); } sleep(1); } } 

De ce fait, les consommateurs n’ont pas access à la zone critique des autres consommateurs, mais aux produits, et inversement. La solution était assez simple, je devais juste append un nom commun pour les domaines critiques et maintenant, un secteur critique pour un consommateur est également essentiel pour un producteur, et vice-versa.

C'est le code correct pour déclarer les zones critiques:

 #pragma omp critical (CRIT)