我有一个std::deque<std::reference_wrapper<MyType>> mydeque
。我需要一个返回前值(作为普通引用)并将其从队列中弹出的函数。如std::deque
不是线程安全的,访问应该受到保护(我正在使用 OpenMP)。
我想出了下面丑陋的代码。拥有如此高级的结构然后又回到原始指针看起来非常糟糕。
MyType & retrieve() {
MyType* b;
#pragma omp critical(access_mydeque)
{
b = &(mydeque.front().get());
mydeque.pop_front();
}
return *b;
}
问题是我无法在关键部分内返回,但我也无法在关键部分之前声明引用(_wrapper)(因为它必须分配给某事)...有办法解决这个问题吗?
最佳答案
我能想到的任何解决方案都涉及使用 omp_lock_t
而不是 ritic
构造以及管理 omp_lock_t
所有权的 RAII 类:
class LockGuard {
public:
explicit LockGuard(omp_lock_t& lock) : m_lock(lock){
omp_set_lock(&m_lock);
}
~LockGuard() {
omp_unset_lock(&m_lock);
}
private:
omp_lock_t& m_lock;
};
然后您可以将已有的代码修改为:
MyType & retrieve() {
LockGuard guard(mydeque_lock);
auto b = mydeque.front();
mydeque.pop_front();
return b;
}
或者更好的是,编写自己的线程安全容器来聚合锁和std::deque
:
template<class T>
class MtLifo {
public:
MtLifo() {
omp_init_lock(&m_lock);
}
typename std::deque<T>::reference front_and_pop() {
LockGuard guard(m_lock);
auto b = m_stack.front();
m_stack.pop_front();
return b;
}
void push_front(const T& value) {
LockGuard guard(m_lock);
m_stack.push_front(value);
}
~MtLifo() {
omp_destroy_lock(&m_lock);
}
private:
std::deque<T> m_stack;
omp_lock_t m_lock;
}
关于c++ - 如何使用此 OpenMP 关键部分避免此原始指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25891296/