OpenMP:并发写入std :: map

时间:2013-11-28 14:02:39

标签: c++ c++11 openmp

我有一个std::map,其密钥与thread_num相同。每个线程都写入值std::vector。因此可以保证每个线程仅在“他的”std::vector上运行。

示例:

#include <iostream>
#include <omp.h>
#include <map>
#include <vector>


int main(void) {

    std::map<unsigned int, std::vector<unsigned int> > M;

// initialize map using first touch policy:
#pragma omp parallel for schedule(static,1)
    for (int i=0; i<omp_get_num_procs(); ++i) {
#pragma omp critical
        M[omp_get_thread_num()] = std::vector<unsigned int>();
    }

// do some parallel operations:
#pragma omp parallel for schedule(static)
    for (int i=0; i<100; ++i) {
        M[omp_get_thread_num()].push_back(i);
    }

// disp the content:
    for (auto it_key : M) {
        std::cout << "thread " << it_key.first << " : {";
        for (auto it_vec : it_key.second) {
            std::cout << it_vec << " ";
        }
        std::cout << "\b \b}" << std::endl;
    }

    return 0;
}

输出看起来符合要求。问题是上述代码是否合法?所以我可以得出结论,我可以并行运行std::map,只要我能保证只有一个线程在特定密钥的辅助数据上运行?

1 个答案:

答案 0 :(得分:5)

您的第二个循环看起来很好,因为您不是在修改地图本身,而只是修改了键下的值。 来自

http://www.cplusplus.com/reference/map/map/operator[]/

数据竞赛 访问容器,并可能进行修改。 该函数访问一个元素并返回一个可用于修改其映射值的引用。 同时访问其他元素是安全的。 如果函数插入一个新元素,则同时迭代容器中的范围是不安全的。

第一个循环可能最好不要同时进行,因为它无论如何都是最小的工作量 - 在一个线程中执行它,然后在syn_threads中执行。它现在的标准似乎并不安全,只是碰巧在你的配置上工作。

修改

实际上,因为在第一个循环中你没有访问其他元素而只是插入新元素,所以标准也是安全的,尽管同时执行它没有任何好处。