Hi writing a very simple example on how to use omp flush to exchange data, in a producer-> consumer way,among threads I have found a funny behavior.
int a=-1;
int flag=1;
int count=0;
#pragma omp parallel num_threads(2)
{
int TID;
TID=omp_get_thread_num();
#pragma omp sections
{
#pragma omp section /////////// Producer
{
for(int i=0; i<9;i++)
{
a=i;
#pragma omp flush(a)
flag=1;
printf("Producer a: %d flag:%d TID %d \n",a,flag,TID);
while(flag)
{
#pragma omp flush(flag)
}
}
flag=2;
#pragma omp flush(flag)
} // end producer
#pragma omp section /////////// Consumer
{
while(1) {
count++;
flag=0;
while(!flag)
{
#pragma omp flush(flag)
}
#pragma omp flush(a)
printf("Consumer a: %d Flag: %d count %d TID %d \n",a,flag,count,TID);
if (flag==2) break; // no more data
} // end while(1)
}// end consumer
}// end sections
Using this very simple code will produce an erroneous output:
Producer a: 0 flag:1 TID 0
Producer a: 1 flag:1 TID 0
Consumer a: 1 Flag: 1 count 1 TID 1
Producer a: 2 flag:1 TID 0
Consumer a: 2 Flag: 1 count 2 TID 1
Producer a: 3 flag:1 TID 0
Consumer a: 3 Flag: 1 count 3 TID 1
Producer a: 4 flag:1 TID 0
Consumer a: 4 Flag: 1 count 4 TID 1
Producer a: 5 flag:1 TID 0
Consumer a: 5 Flag: 1 count 5 TID 1
Producer a: 6 flag:1 TID 0
Consumer a: 6 Flag: 1 count 6 TID 1
Producer a: 7 flag:1 TID 0
Consumer a: 7 Flag: 1 count 7 TID 1
Producer a: 8 flag:1 TID 0
Consumer a: 8 Flag: 1 count 8 TID 1
Consumer a: 8 Flag: 2 count 9 TID 1
The error is that the first datum produced a=0 is ignored by the consumer.
If I simply invert the order of the sections, letting the producer be thread 1 then everything is ok.....
Producer a: 0 flag:1 TID 1
Consumer a: 0 Flag: 1 count 1 TID 0
Producer a: 1 flag:1 TID 1
Consumer a: 1 Flag: 1 count 2 TID 0
....
Whats my mistake ?
..... After the interesting discussion with Ejd (thanks) the code was edited to:
int a=-1;
int flag=0;
int count=0;
#pragma omp parallel num_threads(2)
{
int TID;
TID=omp_get_thread_num();
#pragma omp sections
{
#pragma omp section /////////// Consumer
{
while(1) {
count++;
if (flag) printf("Consumer a: %d Flag: %d count %d TID %d \n",a,flag,count,TID);
flag=0;
while(!flag)
{
#pragma omp flush(flag)
}
if (flag==2) break; // no more data
} // end while(1)
}// end consumer
#pragma omp section /////////// Producer
{
for(int i=0; i<9;i++)
{
a=i;
printf("Producer a: %d flag:%d TID %d \n",a,flag,TID);
flag=1;
while(flag)
{
#pragma omp flush(flag,a)
}
}
flag=2;
#pragma omp flush(flag)
} // end producer
}// end sections
That now works nicely. Thanks !