我有一个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;
}
Run Code Online (Sandbox Code Playgroud)
输出看起来符合要求.问题是上述代码是否合法?所以我可以得出结论,我可以std::map并行操作,只要我能保证只有一个线程在特定键的辅助数据上运行?
你的第二个循环看起来很好,因为你没有修改地图本身,只是在键下修改了值.从
http://www.cplusplus.com/reference/map/map/operator[]/
数据竞争 访问容器,并可能进行修改.该函数访问一个元素并返回一个可用于修改其映射值的引用.同时访问其他元素是安全的. 如果函数插入新元素,则同时迭代容器中的范围是不安全的.
第一个循环可能最好不要同时进行,因为它无论如何都是最小的工作量 - 在一个线程和之后的syn_threads中进行.它现在的方式看起来似乎不安全,只是碰巧在您的配置上工作.
编辑
实际上,因为在第一个循环中你没有访问其他元素而只是插入新元素,所以标准也是安全的,尽管同时执行它没有任何好处.