【发布时间】:2011-02-24 21:40:04
【问题描述】:
您好,写了一个关于如何使用 omp flush 以生产者-> 消费者方式交换数据的非常简单的示例,在线程中我发现了一个有趣的行为。
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
使用这个非常简单的代码会产生错误的输出:
生产者 a:0 标志:1 TID 0
生产者 a:1 个标志:1 个 TID 0
消费者 a:1 个标志:1 个计数 1 个 TID 1
生产者 a:2 标志:1 TID 0
消费者 a:2 标志:1 计数 2 TID 1
生产者 a:3 标志:1 TID 0
消费者 a:3 标志:1 计数 3 TID 1
生产者 a:4 个标志:1 个 TID 0
消费者 a:4 标志:1 计数 4 TID 1
生产者 a:5 个标志:1 个 TID 0
消费者 a:5 标志:1 计数 5 TID 1
生产者 a:6 个标志:1 个 TID 0
消费者 a:6 标志:1 计数 6 TID 1
生产者 a:7 标志:1 TID 0
消费者 a:7 标志:1 计数 7 TID 1
生产者 a:8 个标志:1 个 TID 0
消费者 a:8 标志:1 计数 8 TID 1
消费者 a:8 标志:2 计数 9 TID 1
错误是产生的第一个数据 a=0 被消费者忽略。
如果我只是颠倒部分的顺序,让生产者成为线程 1,那么一切都好.....
生产者 a:0 标志:1 TID 1
消费者 a:0 标志:1 个计数 1 个 TID 0
生产者 a:1 个标志:1 个 TID 1
消费者 a:1 标志:1 计数 2 TID 0
……
我的错误是什么?
..... 在与 Ejd 进行了有趣的讨论(谢谢)之后,代码被编辑为:
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
现在效果很好。谢谢!
【问题讨论】:
-
小错误....最后输出的第一行开头是:Producer a: 0 flag:1 TID 1