【发布时间】:2020-01-05 17:20:05
【问题描述】:
我有一个函数memoize,它读写一个静态的std::map,例如:
int memoize(int i)
{
static std::map<int,int> map;
const auto iterator = memoizer.find(i);
if (iterator == memoizer.end())
memoizer[i]=i+1;
else
return iterator->second;
}
memoize 被其他函数调用,而其他函数又被其他函数调用,而这些函数又被main 中的函数调用。现在如果在main 我有类似的东西
#pragma omp parallel for
for (int i=0; i<1000; i+++)
f(i); \\function calling memoize
for (int i=0; i<1000; i+++)
g(i); \\function calling memoize
然后我在第一个循环中遇到问题,因为std::map 不是线程安全的。我试图找出一种仅在使用 openmp 时才锁定静态地图的方法(因此仅适用于第一个循环)。我宁愿避免重写所有函数来获取额外的omp_lock_t 参数。
实现这一目标的最佳方法是什么?希望使用尽可能少的宏。
【问题讨论】:
-
考虑拥有两个独立的函数:一个是线程安全的,一个不是。
-
@freakish 有没有线程安全的替代
std::map?以及如何从内部检测我是否在 openmp 区域中? -
我的建议是不检测任何东西。您编写了两个函数,由调用者决定使用哪一个。在您的情况下,最简单的线程安全是锁定静态std::mutex。不过有更高效的并发地图,你必须谷歌它。
-
@freakish 调用者不直接调用这些函数,而是其他函数调用函数......调用这两个替代方案。因此标题中的“嵌套”
-
如果内存化值得花时间与多线程同步,那么如果单个线程锁定互斥锁(即使不需要)也可能没问题。
标签: c++ multithreading thread-safety openmp