それは本当のようですが、私の考えは濁っています。誰かが明確な説明と、ロックせずに常に機能するいくつかの重要なケースを提供できますか? ありがとう!
2 に答える
単一のプロデューサーと単一のコンシューマーの循環キューの背後にある本当のトリックは、ヘッド ポインターとテール ポインターがアトミックに変更されることです。これは、メモリ内の位置が値 A から値 B に変更された場合、値が変更されている間にメモリを読み取るオブザーバー (つまりリーダー) は、結果として A または B のいずれかを取得することを意味します。
そのため、たとえば、16 ビット ポインターを使用していて、それらを 2 つの 8 ビット ステップで変更している場合、キューは機能しません (これは、CPU アーキテクチャとメモリ アライメントの要件によって発生する可能性があります)。この場合、リーダーは完全に間違った一時的な値を読み取る可能性があります。
したがって、ポインタがプラットフォームでアトミックに変更されていることを確認してください!
これは確かに巡回キューの実装に依存します。ただし、私が想像しているとおりであれば、キューのhead
と の2 つのインデックスがあります。tail
プロデューサーは を使用しtail
、コンシューマーは を使用しhead
ます。これらはメッセージ配列を共有しますが、2 つの異なるポインターを使用します。
プロデューサとコンシューマが競合する可能性がある唯一のケースは、コンシューマが新しいメッセージをチェックし、チェックの直後に到着する場合です。ただし、そのような場合、消費者は少し待ってからもう一度確認します。プログラムの正確性は失われません。
単一のプロデューサーと単一のコンシューマーで問題なく動作する主な理由は、2 人のユーザーが多くのメモリを共有していないためです。複数のプロデューサーの場合、たとえば複数のスレッドがアクセスしhead
、競合が発生する可能性があります。
編集dasblinkenlight が彼のコメントで言及しているように、私の推論は、両方のスレッドが消費/生成の最後の操作としてそれぞれのカウンターをインクリメント/デクリメントする場合にのみ当てはまります。