我的问题与此类似:How to use lock in OpenMP?
从某种意义上说,他们的回答可以回答我的问题,但还不够好。
我试图在OpenMP中(从头开始)实现一个简单的窃取工作调度程序。
假设我有一些对象的数组,例如int。我有多个线程将以不特定的顺序操作该数组的条目。我想确保没有两个线程尝试同时访问数组的同一元素。但是,我允许线程访问同一元素,只要访问不是同时进行的。另外,只要每个线程希望在这段时间内访问数组的不同条目,我就允许线程同时访问数组。我可以使用关键部分,如下所示:
int array[1000];
#pragma omp parallel
{
bool flag = true;
while(flag){
int x = rand()%1000;
#pragma omp critical
{
array[x] = some_function(array[x]);
if (some_condition(array[x])){
flag = false;
}
}
}
}
这段代码创建了一些线程,这些线程随机访问和操纵数组的条目,直到某些终止条件杀死了该线程。这段代码可以正常工作,因为关键部分可以确保没有两个线程同时写入数组(如果它们生成相同的x值)。但是,如果在某个时间两个线程没有碰巧生成相同的x值,则关键部分是多余的,因为它们的线程不在访问同一条目。有没有一种方法可以使线程在且仅当其生成的x的值与当前也在使用x的线程相同时才停止运行?现在,即使每个线程碰巧生成不同的x值,此代码也效率不高,并且基本上是串行的。我要这样做,以便只有在发生碰撞时它们才停转。
也许我正在寻找的是锁,但是我不确定。关键部分不是正确的方法吗?
最佳答案
我的意思是这样的:
#include <stdlib.h>
#include <omp.h>
int main()
{
int array[1000];
omp_lock_t locks[1000];
for (int i = 0; i < 1000; i++)
omp_init_lock(&locks[i]);
#pragma omp parallel
{
bool flag = true;
while(flag){
int x = rand()%1000;
omp_set_lock(&locks[x]);
array[x] = some_function(array[x]);
if (some_condition(array[x])){
flag = false;
}
omp_unset_lock(&locks[x]);
}
}
for (int i = 0; i < 1000; i++)
omp_destroy_lock(&locks[i]);
}
关于c++ - 仅在存在数据竞争与锁定的情况下才存在OpenMP关键部分?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49500249/