访问类数据时替代互斥锁定/解锁

时间:2011-06-09 18:14:10

标签: c++ mutex openmp

我试图让my_class线程安全如此。

class my_class
{
  const std::vector<double>& 
  get_data() const
  { //lock so that cannot get_data() while setting data
    lock l(m_mutex);
    return m_data;
  }

  void
  run()
  {
    vector<double> tmp;
    //some calculations on tmp.
    {  //lock so that cannot get_data() while setting m_data
      lock l(m_mutex);  
      m_data = tmp;  //set the data
    }
  }

private:
  std::vector<double> m_data;
  mutex m_mutex;
  my_class(); //non-copyable
}

run()get_data()可能由不同的openmp线程调用,因此我引入了一个锁。 (因为我使用openmp,m_mutexlock是围绕omp_init_lock();等命令的RAII包装器。

但是,get_data ()上的锁定对于创建和销毁是很昂贵的(当我分析我的代码时,这是最昂贵的操作 - 我经常调用get_data())。

是否可以重新组织my_class以移除get_data()中的锁定?或者这种锁定是不可避免的并行代码成本?

2 个答案:

答案 0 :(得分:3)

第一步是研究读写锁:这样多个读者就不会相互阻塞。

下一步是使用无锁或无等待操作。网上有很多资源比我能够更好地描述它们。只需注意一点:无锁方法处理原子(互锁)操作,这意味着数据大小需要很小。如果你走这条路,你将原子地替换一个指向你的向量的指针,而不是整个向量。这意味着你的类会变得更复杂,并会处理一些指针和内存管理。

答案 1 :(得分:0)

在get_data / run函数周围使用关键部分可能更便宜,不会产生额外的设置/拆除开销(因为关键部分是静态初始化的),但这也会同步该类的其他实例。