2013-01-03 3 views
5

それは本当だと思うけど、私の考えは泥だ。 誰かが明確な説明とそれが常にロックなしで動作するいくつかの重要なケースを与えることができますか?ありがとう!シングルプロデューサのシングルコンシューマサーキュラキューは、ロックされていないスレッドセーフなのはなぜですか?

+1

この申し立てのソースまたは文脈は何ですか?単一のセマフォで実装することはできますか?それはあなたが参照しているものですか?セマフォも内部にロックを持っているか、ハードウェアではアトミックです。 – ypnos

+0

メモリモデルの問題のためにのみ、主張が一般的に真実であった場合、私は驚くでしょう。プロデューサが行った変更を消費者に見せてくれるのは何か?揮発性および/またはアトミックな操作をいくつか使用して、安全な非ロック実装を記述することは可能かもしれませんが、多くのデータ構造に対して行うことができます。 –

+0

これは、循環キューが合理的にうまく実装されていれば、コンテキストに関係なく一般的に真実だと思います。単一の消費者、単一プロデューサで使用するためのロックは必要ありません。問題は、すべての紛争事件がどのように正しく処理されるかです。 –

答えて

1

これは、確実に循環キューの実装に依存します。しかし、それが想像している通りであれば、あなたは2つの指標、headtailのキューを持っています。プロデューサーはtailで、消費者はheadで働いています。それらはメッセージ配列を共有しますが、2つの異なるポインタを使用します。

プロデューサとコンシューマが競合する可能性がある唯一のケースは、消費者は新しいメッセージをチェックし、チェックの直後に到着する。しかし、そのような場合、消費者は少し待ってからもう一度チェックします。プログラムの正しさは失われません。

単一プロデューサの単一コンシューマで正常に動作するのは、主に2人のユーザーがメモリを共有しないためです。例えば複数の生産者の場合。 headにアクセスするスレッドが2つ以上あり、競合が発生する可能性があります。

EDIT dasblinkenlightは彼のコメントに言及しているように私の推論は、両方のスレッドがインクリメント/生産彼らの消費/最後の操作として、それぞれのカウンタをデクリメントする場合にのみ当てはまります。

+1

+1スレッドの安全性は、プロデューサが項目を最初にキューに書き込んだ後、 'tail'インデックスをインクリメントすることだけを条件としていることに言及する必要があります。シングルスレッド環境では、順序は関係ありませんが、並行環境では順序を切り替えることで事態が壊れてしまいます。 – dasblinkenlight

+0

@dasblinkenlightありがとう、合理的なコメント。 –

+0

@dasblinkenlight同じ行に沿って、消費者も最初に項目を処理してから、__head__インデックスをインクリメントする必要がありますか? –

0

単一のプロデューサ - 単一のコンシューマ循環キューの背後にある本当のトリックは、頭と尾のポインタがアブドルに変更されていることです。。これは、メモリ内の位置が値Aから値Bに変更された場合、その値が変更されている間にメモリを読み取るオブザーバ(すなわちリーダ)は結果としてAまたはBのいずれかを取得することを意味する。

たとえば、16ビットポインタを使用していても、2つの8ビットステップで変更している場合(CPUアーキテクチャとメモリアラインメントの要件によって異なる場合があります)、キューは機能しません。この場合、読者は完全に間違った過渡値を読み取る可能性があります。

あなたのポインタがあなたのプラットフォームでアトミックに変更されていることを確認してください!