我的问题与此相似:如何在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]);
}