【问题标题】:lock of openmp seems not to work when dong summation当 dong summation 时,openmp 的锁似乎不起作用
【发布时间】:2022-01-18 16:15:01
【问题描述】:

我是 openMP 和多线程的新手。我需要做一些求和工作,我知道在写入共享变量时,它需要使用像omp_lock_t 这样的锁。但是当我这样做时,结果仍然出错。

代码是:

#include <omp.h>

#include <cstdio>
struct simu
{
public:
    simu() : data{ nullptr }
    {
        omp_init_lock(&lock);
    }
    ~simu()
    {
        omp_destroy_lock(&lock);
    }
    void calcluate()
    {
        omp_set_lock(&lock);
        (*data) += 1;
        omp_unset_lock(&lock);
    }
public:
    omp_lock_t lock;
    int *data;
};

int main()
{
    printf("thread_num = %d\n", omp_get_num_procs());

    const int size = 2000;
    int a = 1;
    int b = 2;

    simu s[size];
    simu *ps[size];
    for (int i = 0; i < size; ++i)
    {
        s[i].data = (0 == i % 2) ? &a : &b;
        ps[i]     = &s[i];
    }

    for (int k = 0; k < size; ++k)
    {
        ps[k]->calcluate();
    }

    printf("a = %d, b = %d\n", a, b);

    a = 1;
    b = 2;

    #pragma omp parallel for default(shared) num_threads(4)
    for (int k = 0; k < size; ++k)
    {
        ps[k]->calcluate();
    }

    printf("a = %d, b = %d\n", a, b);

    return 0;
}

结果是

thread_num = 8
a = 1001, b = 1002
a = 676, b = 679

我在 Win10 上运行此代码。谁能解释为什么结果是错误的?

【问题讨论】:

  • 什么是“正确”的输出?
  • simu 的每个实例似乎都有自己的锁。所以锁是没有价值的,你有竞争条件访问 a 和 b。
  • 风格要点:不要使用旧式数组。特别是simu *ps[size] 看起来没有必要。请使用std::vector 来处理所有类似数组的内容。你的代码中的星星通常太多了。

标签: c++ multithreading openmp


【解决方案1】:

锁保护实际数据项不被同时写入。您的锁位于指向该项目的对象中,因此这是没有意义的。你需要让你data指向一个包含锁的对象。

【讨论】:

  • 我明白了。所以我需要分别为ab 锁定。但现在我只是锁定data,它不会改变。谢谢!
  • 就是这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 2017-12-31
  • 1970-01-01
  • 2016-11-29
  • 2016-02-01
相关资源
最近更新 更多