0

これが些細な質問である場合は申し訳ありません。しかし、私はどこにも答えを見つけることができませんでした。pthreads を使用するプログラムを作成しています。1 つのスレッドがロック (ミューテックス) を取得し、データを同期バッファーにプッシュしようとします。バッファには、 push()メソッドが呼び出されると取得される独自のミューテックスがあります。

バッファーがいっぱいで、スレッドが条件変数で待機する必要がある場合、待機呼び出しは取得したすべてのロックを解放しますか? それとも、条件変数に関連付けられたもの (たまたま最後に取得されたロック) を解放するだけですか? 後者の場合、別のスレッドが最初のロックを取得する必要がある場合、どうすればデッドロックを回避できますか?

編集:

私が抱えている問題は次のとおりです。ABという 2 つのスレッドがあります。スレッドAには、多数のバッファにデータを挿入するforループがあります。反復ごとに要素がバッファの 1 つに挿入されます。これはスレッドであるため、スレッドの別の外側のループ内でこのループを継続的に実行します。Bがアクティブになると、これらのバッファーを操作します。ただし、 forループの実行中にAがスケジューラによって中断された場合、 Bはバッファを操作してはなりません。したがって、ミューテックスを使用して、forループであるAのクリティカル セクションをロックします。

編集-2:

私はそれにいくつかの考えを与えてきました。そして、私の問題に対する答えは、バッファの条件変数が最初のロックも解放するということではありません。つまり、最初のロックはそもそも必要ありませんでした。バッファからの要素の削除を担当するコンシューマ スレッド (スレッドBとは異なります) が適切にジョブを実行している場合、スレッドAはある時点で再開し、forループは完了します。したがって、私の問題はそこにあるに違いありません。詳しく見て更新していきます。

4

1 に答える 1

0

pthread_cond_wait()渡したミューテックスのみを解放します。この場合、push()呼び出し内で以前に取得したバッファーのミューテックスになります。

あなたの状況ではデッドロックの可能性があるように思えますが、それはあなたのハイレベルな設計の結果です。スレッド A がループを実行している間はスレッド B を実行できないが、そのfor()ループ内でfor()スレッド A がスレッド B が処理を進めるためにデータを消費するのを待たなければならない場合、デッドロックは避けられません。

これを考慮して設計を更新する必要があります。1 つの可能性はreserve()、後続の のためにスペースを確保するpush()が、データを追加しない関数を同期バッファーに追加することです。その後、スレッド A は、外側のミューテックスを保持せずに必要なスペースを通過して予約できます(スレッド B に表示されるデータをまだ追加していないため) - スレッド B がデータを消費するのを待つ必要がある場合は、そうします。ここ。必要なすべてのスペースを予約すると、外側のミューテックスをロックしてデータをプッシュできます。これは、スペースがすでに予約されているため、スレッド B を待つ必要がないことが保証されています。

于 2013-10-29T03:46:35.267 に答える