2016-04-06 13 views
0

私はC++でマルチスレッドプログラムを書いています。このプログラムでは、pthread_tをキーとし、値としてのペアを含むグローバルマップオブジェクトを使用しました。 ペアは値によって挿入されます(make_pairを使用)。 このペアには、値によって挿入されたリストが最初の要素として含まれています。このリストに私は読んで書いてみたいと思います。 (2番目の要素はpthread_mutex_tです)C++のリストは空ではありませんが、反復する要素はありません

まあ、私はリストの書き込み操作を制御するために私が使用するmutexを持っています。私はリストにプッシュする要素が成功したことも分かりました。 とにかく、スレッドでlist.emptyメソッドを使って、それをXとしましょう。リストが空でないことがわかりました(特定の設計では問題にはならないミューテックスがないことを確認してください)。したがって、私はリストをロックし、要素を反復するためにミューテックスを使用しました。しかし、反復は起こらなかった。リストに要素がないように行動する。

ここにコードスニペストがあります。ちなみに、私はpthread_tを使いたいが、別のオプションは使用しない。

挿入 - チェックしましたが、動作します: ThreadData & data = threadsOutput [my_key];

data.first.push_back(std::make_pair<Obj1*, Obj2*>(std::move(key),std::move(value))); 

反復処理:関連リストは

// the list is not empty, so running: 

ThreadData& data = threadsOutput[my_key]; 

if (pthread_mutex_lock(&(data.second))) // data.second is the relevant pthread_mutex_t 

    return; // not arrives here - lock succeeded 


MapResult::iterator it = data.first.begin(); 

for (; it != data.first.end(); ++it) 

{ 

    //some code - not arrives to this code 

} 

おかげ空の場合 //いくつかのコードがチェックします!

+0

リファレンスを取得してから実際にミューテックスをラッチするまでの間に、マップが変更されることを防ぎます。 – WhozCraig

+0

"私の特定の設計では問題とは思わないミューテックスを使わないでチェックする" - どのような魔法の設計では、(a)正しく動作し、(b)ミューテックスは開催されましたか? – davmac

+0

この問題は修正されていませんが、プログラムの一般的な流れは、スレッドがデータを見落とした場合(スレッドが間違った答えを得たため)、このデータは後で処理されるように動作します。 –

答えて

3

mutexを保持していないリストがempty()でないかどうかをチェックするとします。しかし、empty()はスレッドセーフな方法ではありません。別のスレッドでリストを(潜在的に)同時に変更している間は、呼び出さないでください。

リストから項目を削除するコードはありますか?リストが空でない場合、リストが処理される前に空になります。

+0

リストからアイテムを削除する唯一のスレッドは、リストのアイテムを反復するスレッドです。私は空のスレッドセーフではないが、なぜこれは問題であると思われるのですか?ミューテックスをロックするための呼び出しの前にこのチェックを行うのは、コードを最適化するためで、ミューテックスは本当に必要なときにロックされます。データが失われる可能性がありますが、後で処理され、この問題の一部ではありません(私はそう信じています)。ありがとう! –

+0

あなたは、より良い推測をするのに十分なコードを表示していません。おそらく 'empty()'と呼んでいるリストと、反復処理中のリストは別のリストです。あなたがそれが空であるとすぐにリストの要素の数と数を印刷して、それを繰り返す直前にもう一度印刷してみてください。そして、技術的には、リストへの同時アクセスがあるときに 'empty()'を呼び出すと、未定義の動作が発生し、_anything_が発生する可能性があります。 – davmac

関連する問題