访问类数据时互斥锁/解锁的替代方案

发布于 2024-11-14 11:33:30 字数 949 浏览 1 评论 0原文

我试图像这样使 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_mutexlockomp_init_lock(); 等命令的 RAII 包装器)。

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

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

I am trying to make my_class thread-safe like so.

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() and get_data() may be called by different openmp threads and so I introduce a lock.
(Since am using openmp, m_mutex and lock are RAII wrappers around omp_init_lock(); etc. commands).

However, the lock on get_data () is expensive to create and destroy (The most expensive operation when I profile my code - I call get_data() a lot).

Is is possible to reorganise my_class to remove the lock in get_data()? Or is this lock the unavoidable cost of parallelising the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白云不回头 2024-11-21 11:33:30

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

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

First step would be to look into read-write locks: this way multiple readers will not block each other.

The next step would be using lock-free or wait-free operations. There are plenty of resources online describing them better than I would be able to. Just one note: lock-free approaches deal with atomic (interlocked) operations, which means the data size needs to be small. If you go this route, you'll be atomically replacing a pointer to your vector, not the whole vector. This means your class will get a bit more complex and will deal with some pointers and memory management.

救赎№ 2024-11-21 11:33:30

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

It may be cheaper to use a critical section around get_data/run functions, you will not incur additional setup/teardown overhead (as the critical section is statically initialized), but this would also synchronize other instances of the class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文