9

私のプログラムでは、いくつかのスレッドを実行しています。各スレッドは、いくつかのオブジェクトへのポインターを取得します (私のプログラムでは - ベクトル)。そして、各スレッドはベクトルを変更します。

また、プログラムがセグメント フォールトで失敗することもあります。スレッドBがベクターの操作を完了していないときに、スレッドAがベクターで何かを開始したために発生したと思いましたか? それは本当ですか?

どうすれば直せますか?スレッド同期?または、フラグを作成し、VectorIsInUse操作中にこのフラグを true に設定しますか?

4

3 に答える 3

14

vector、すべてのSTLコンテナと同様に、スレッドセーフではありません。同期を自分で明示的に管理する必要があります。またははstd::mutexboost::mutexへのアクセスを同期するために使用できますvector

フラグはスレッドセーフではないため、使用しないでください。

  • スレッドAはisInUseフラグの値をチェックします。false
  • スレッドAは中断されています
  • スレッドBはisInUseフラグの値をチェックします。false
  • スレッドBはに設定isInUseしますtrue
  • スレッドBは中断されています
  • スレッドAが再開されます
  • スレッドAはまだそうだと考えisInUsefalse設定しますtrue
  • スレッドAとスレッドBの両方がアクセスできるようになりましたvector

vector各スレッドは、それを使用する必要がある間ずっとをロックする必要があることに注意してください。これには、イテレータが参照する要素が内部再割り当てであるか、内部再割り当てが行われる場合にイテレータが無効になる可能性があるため、イテレータの変更vectorと使用が含まれます。たとえば、次のことはしないでください。vectorerase()vector

mtx.lock();
std::vector<std::string>::iterator i = the_vector.begin();
mtx.unlock();

// 'i' can become invalid if the `vector` is modified.
于 2012-09-04T10:02:01.520 に答える
4

多くのスレッドから安全に使用できるコンテナーが必要な場合は、その目的のために明示的に設計されたコンテナーを使用する必要があります。標準コンテナーのインターフェースは、同時ミューテーションやあらゆる種類の並行性のために設計されていないため、問題にロックをかけることはできません。

TBB や PPL のようなものが必要ですconcurrent_vector

于 2012-09-04T10:09:44.190 に答える
1

そのため、スレッドを提供するほとんどすべてのクラスライブラリには、ミューテックス/ロックなどの同期プリミティブもあります。これらのいずれかを設定し、共有アイテムのすべての操作のロックを取得/解放する必要があります(複数の書き込みが同時に発生するのを防ぐだけでなく、書き込み中にも読み取りが発生しないようにする必要があるため、読み取りと書き込みの操作)。

于 2012-09-04T09:58:26.763 に答える