我的问题与此类似: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/

10-10 09:46