14

それは本当のようですが、私の考えは濁っています。誰かが明確な説明と、ロックせずに常に機能するいくつかの重要なケースを提供できますか? ありがとう!

4

2 に答える 2

6

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

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

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

于 2017-09-13T06:59:20.857 に答える
4

これは確かに巡回キューの実装に依存します。ただし、私が想像しているとおりであれば、キューのheadと の2 つのインデックスがあります。tailプロデューサーは を使用しtail、コンシューマーは を使用しheadます。これらはメッセージ配列を共有しますが、2 つの異なるポインターを使用します。

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

単一のプロデューサーと単一のコンシューマーで問題なく動作する主な理由は、2 人のユーザーが多くのメモリを共有していないためです。複数のプロデューサーの場合、たとえば複数のスレッドがアクセスしhead、競合が発生する可能性があります。

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

于 2013-01-03T15:38:33.747 に答える