【问题标题】:How to use boost::thread mutex to synchronize write access?如何使用 boost::thread 互斥锁来同步写访问?
【发布时间】:2010-09-17 22:37:06
【问题描述】:

我有一个关于Boost::ThreadMutex 的新手问题。

我想启动以下Worker的多个并行实例,并且它们都写入同一个std::vector

struct Worker {
  std::vector<double>* vec;
  Worker(std::vector<double>* v) : vec(v) {}
  void operator() {
    // do some long computation and then add results to *vec, e.g.
    for(std::size_t i = 0; i < vec->size(); ++i) {
      (*vec)[i] += some_value;
    }
  }
};

我知道 Worker 必须在写入之前锁定 vec 并在完成后解锁它(因为所有 Worker 都写入同一个向量)。但是我该如何表达呢?

【问题讨论】:

    标签: multithreading mutex boost-thread


    【解决方案1】:

    您需要一个 boost::mutex 来保护向量,并且您可以使用 boost::mutex::scoped_lock 将互斥锁锁定在其构造函数中,并在析构函数中解锁它

    请记住,您需要在访问vec 实例的任何地方使用相同的互斥锁,无论是读取还是写入。

    为了让您继续前进,您可以执行以下操作:

    struct Worker {
      boost::mutex &vec_mutex;
    
      Worker(std::vector<double>* v,boost::mutex &v_mutex) : vec(v),vec_mutex(v_mutex) {}
      void operator() {        
        // do some long computation and then add results to *vec, e.g.
    
        boost::mutex::scoped_lock lock(vec_mutex);
        for(std::size_t i = 0; i < vec->size(); ++i) {
          (*vec)[i] += some_value;
        }
      }
    
    };
    

    对于更高级的东西,你应该进一步封装向量和互斥锁,或者迟早你会忘记这些需要连接,你会在不持有锁的情况下访问vec,导致非常难以调试问题。对于像这个例子这样的问题,我宁愿让工作人员使用他们自己的个体向量,并在工作人员完成后将结果组合到控制线程中。

    【讨论】:

    • 您的意思是vec_mutex 而不是io_mutex
    【解决方案2】:

    OT 但我希望提供有用的信息 - 因为您正在更新这个向量很多(或只是为了最佳实践)考虑 iterators 迭代向量元素。通过不使用vector&lt;double&gt;::operator[] 使工作代码更快,将减少工作线程的总等待时间。

    for(std::vector<double>::iterator iter = vec->begin(); iter != vec->end(); ++iter) {
      *iter += some_value;
    }
    

    【讨论】:

    • 你确定这样更快吗?有证明链接吗?
    • 迭代器减少为指针增量。索引需要重复指针解引用(通过局部变量vec 获取向量),然后乘以解析operator[]。一个好的优化编译器可能能够将它们折叠成相同的东西,但为什么要冒险呢?建议您编写两者并比较在您的特定编译器上生成的汇编代码。
    猜你喜欢
    • 1970-01-01
    • 2013-01-01
    • 2011-06-10
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 2014-01-02
    • 2022-06-13
    • 1970-01-01
    相关资源
    最近更新 更多