c++ - 如何使用此 OpenMP 关键部分避免此原始指针?

标签 c++ c++11 reference openmp

我有一个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/

相关文章:

c++ - 计算二进制中连续的 1

c++ - 调整 std::vector 的大小是否可能会降低其容量?

c++ - 通过指针转换将右值绑定(bind)到非常量引用?

c++ - 为什么从constexpr引用生成的汇编代码与constexpr指针生成的汇编代码不同?

string - 如何使用Box <String>作为具有&str键的 HashMap 的查找键?

c++ - Stitcher 类 OpenCV

c++ - 嵌套循环导致复杂性效率降低?

c++ - unsigned long long 数组的 sse 总和

c++ - 标准布局 c++

c++ - 在 [] 运算符的情况下,为 unordered_map 中的元素设置默认构造函数