OpenMP Producer-Consumer意外结果

我正在研究一个简单的生产者 – 消费者问题,在C中使用OpenMP。

我的程序创建了4个线程,其中两个是消费者,两个是生产者。 每个制作人将一个角色放在一个缓冲区中,消费者只需打印该角色。

我的目标是同步生产者/消费者,以便每个生产者将生成字母表中的下一个按顺序字符,并且每个消费者将打印放置在缓冲区中的下一个按顺序字符。

这是我的代码:

#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); } } } 

这是输出:

 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 

那些没有打印字符的空行表示我没有实现我应该的同步。 我错过了什么?

提前感谢您的任何帮助或想法。

所以@Jlghtuse是正确的,有数据竞争,这是因为关键区域的错误声明。

你看我宣布我的关键领域:

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

 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); } } 

这导致消费者无法进入其他消费者关键区域,但生产有,反之亦然。 解决方案相当简单,我只需要为关键区域添加一个通用名称,现在消费者的关键区域对于生产者来说也是至关重要的,反之亦然。

这是用于声明关键区域的正确代码:

 #pragma omp critical (CRIT)