4

と について初心者に質問がBoost::Threadあり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;
    }
  }
};

ワーカーは書き込む前にロックし、完了したらロックを解除する必要があることを理解していますvec(すべてのワーカーが同じベクターに書き込むため)。でもそれをどう表現すればいいの?

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、ロックを保持せずにどこかにアクセスするようになり、デバッグが非常に困難になります。この例のような問題では、ワーカーに独自の vector を使用させ、ワーカーの処理が完了したときに制御スレッドで結果を結合させたいと考えています。

于 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 に答える