4

Boost::Thread我有一个关于and的新手问题Mutex

我想启动以下许多并行实例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 都写入同一个向量)。但是我该如何表达呢?

4

2 回答 2

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;
    }
  }

};

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

于 2010-09-17T23:20:28.940 回答
0

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

for(std::vector<double>::iterator iter = vec->begin(); iter != vec->end(); ++iter) {
  *iter += some_value;
}
于 2010-09-18T12:57:27.203 回答