c/c++语言开发共享#pragma omp flush在线程之间建立交换数据

你写了一个非常简单的例子,说明如何使用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 

现在效果很好。 谢谢 !

    不幸的是,使用flush比初看起来要复杂得多。 即使是OpenMP的专家也无法正确使用它。 问题的一部分是,列表的刷新定义很糟糕。 基本上它是允许移动的,所以如果你有一个forms的序列:

     a = ... #pragma omp flush(a) b = ... #pragma omp flush(b) 

    冲洗(a)必须在设置a之后,但可以在设置和冲洗(b)之后移动。 它必须在下次使用之前发生。

    在任何情况下,执行所需操作的最佳方法是在没有列表的情况下使用flush,并在您感兴趣的每个变量集之后执行刷新,并在读取您感兴趣的每个变量之前执行刷新。

    另一个问题是你没有正确交接。 您不能在消费者中为生产者设置标志,以便在消费者实际消费所产生的价值之后生成另一个数字。

      以上就是c/c++开发分享#pragma omp flush在线程之间建立交换数据相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/541705.html

      (0)
      上一篇 2021年1月3日
      下一篇 2021年1月3日

      精彩推荐