如何使用boost :: thread mutex来同步写访问?

时间:2010-09-17 22:37:07

标签: multithreading mutex boost-thread

我有一个关于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;
    }
  }
};

我理解工作者必须在写入之前锁定vec并在完成时将其解锁(因为所有工作者都写入相同的向量)。但是我该怎么表达呢?

2 个答案:

答案 0 :(得分:8)

你需要一个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;
    }
  }

};

对于更高级的东西,你应该进一步封装vector和mutex,或者迟早你会忘记这些需要连接,你可以在某个地方访问vec而不需要锁定导致非常困难调试问题。对于像这个例子这样的问题,我宁愿让工人使用他们自己的单独的向量,并在工人完成时将结果组合在一个控制线程中。

答案 1 :(得分:0)

OT但有用的信息我希望 - 因为你正在更新这个向量(或者只是为了最佳实践),考虑iterators迭代向量元素。通过不需要使用vector<double>::operator[]来提高工作者代码将减少工作线程的总等待时间。

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