STL / OpenMP在64位版本中出现奇怪的并发问题
当我在64位调试配置中构建我们的一个项目时,我有一个奇怪的问题。它似乎产生了一些奇怪的行为,看起来有点像单个迭代器多次递增。我把它缩小到以下测试代码:
#include <omp.h>
#define _HAS_ITERATOR_DEBUGGING 0
#include <vector>
#include <set>
int main(int argc, const char* argv[]) {
std::vector<int> v;
for(int j = 0; j < 20; ++j) {
v.push_back(j);
}
#pragma omp parallel for
for(int i = 0; i < 100000; ++i) {
std::set<int> s;
std::vector<int>::const_iterator begin = v.begin(), end = v.end();
s.insert(begin, end); // after this line s should contain the numbers 0-19
if(s.size() != 20) {
printf("failn");
exit(3);
}
}
return 0;
}
但是,大小测试经常失败,这意味着它不会以某种方式插入向量的整个内容 - 并且对它进行大量的调整使得它看起来更像是向量迭代器一次增加多个步骤。这很难说,因为如果用调试器中断,它就不会发生。
绘制的明显结论是它不是线程安全的,但我的理解是它应该是因为唯一修改的变量是具有局部范围的s
。
有很多东西可以解决眼前的问题:
删除并行
在insert()
电话周围抛出关键部分
#define HAS_ITERATOR_DEBUGGING 1
用手动循环替换单个insert()调用并单独插入每个项目(这基本上是该函数在内部执行的操作,但是当我自己执行时问题肯定会消失)
构建相同代码的32位版本
构建相同代码的发布版本
这是在MSVC ++ 2008 SP1下编译的,带有编译器提供的STL实现。
任何人都可以了解这里发生的事情吗?提前感谢任何提示 - 我很难过:)
编辑:如果不清楚,我不是在寻找一个“快速修复”来使这个代码工作;如上所述,我知道其中很多。我想要了解的是为什么这个问题首先发生。
编辑2:使用gcc编译时代码正常工作。
没有找到相关结果
已邀请:
3 个回复
赣借
骇毖煽洁铂
标为私人
氏脑