2009-07-05 13 views
11

私は、単一のプロデューサ - 単一のコンシューマのためのいくつかの実装を見出しましたが、複数のプロデューサ - 単一のコンシューマのためのものは見つかりませんでした。Delphiのロックフリーキュー「複数のプロデューサ - 単一のコンシューマ」が存在しますか?

Delphiでは「複数のプロデューサ - 単一のコンシューマ」のロックフリーキューが存在しますか?

+1

Aロックフリーアルゴリズムおよび代替を使用して、パフォーマンス・チューニングに関する非常に興味深い答え:http://stackoverflow.com/questions/853316/is-critical-section-always-faster/853510#853510。 – mghie

答えて

5

OmniThreadLibraryからのロックフリーキューは、複数のプロデューサをサポートします。スレッドライブラリとは別に使用できます(つまり、他のフレームワークではOtlContainersユニットを使用できます)。

Danieleが次に指摘したように、OmniThreadLibraryには2つのキューがあります。 OtlContainerの1つは複数のプロデューサと複数のコンシューマをサポートしますが、OtlCommの「よりスマートな」バージョン(より単純なバージョンのラッパー)は、単一のプロデューサ/単一のコンシューマです。

ドキュメント:(まだOmniThreadLibraryプロジェクトの大きな問題である。キューの一部の情報がhere見つけることができます。

+0

本当に?私はあなたのリストを使用しましたが、ソースコードでは私にとって「悲しい」コメントです... "{:ロックフリー、シングルライター、シングルリーダーリングバッファ。 } IOmniQueueは=インターフェース[ '{AE6454A2-CDB4-43EE-9F1B-5A7307593EE9}']」 あなたはシングル、消費者が、申し訳ありませんが私のミスを? –

+0

を有効にし、OmniQueueはMULTI生産者であると言う。 "OtlCommにおける高レベル" キュー単一のプロデューサ/単一のコンシューマです。OtlContainersの「低レベル」キューは複数のプロデューサ/複数のコンシューマですので、複数のプロデューサを使用する場合は、キューオブジェクトのより単純なバリアントを使用する必要があります。 正しい装置名を参照してください。 – gabr

3

これは参考になる可能性があります:Interlocked SList functions

+0

+1。アプリケーションがXP以前のWindowsシステムで動作する必要がある場合は、これに代わる方法を実装する必要があります。また、コンシューマブロックを空のキューに入れるのは簡単な方法ではないことにも注意してください。 – mghie

+0

SList関数は、キューではなくスタックを生成します。 –

+2

@Robケネディ:完全に真なく、消費者がInterlockedFlushSListを(使用する場合)の代わりにInterlockedPopEntrySListの()には、両方向のリスト項目を処理して自由です。 – mghie

2

http://svn.berlios.de/svnroot/repos/dzchart/utilities/dzLib/trunk/lockfree/

@Danieleテティ:

読者はまだエンキューメソッドを終了し古いキューへのアクセス権を持つすべてのライターを待つ必要があります。読者がDequeueメソッドで行う最初のことは、新しいキューを提供することです。新しいキューはキューに入れられます。古いキューへの参照を持つすべてのライターがEnqueueを終了するのに時間がかかるべきではありません。しかし、あなたは正しい:それは作家のためのロックフリーですが、まだいくつかの作家がエンキューを終了するのを待つために読者スレッドを必要とするかもしれません。

+1

は、私はこのリストをトリングだけど...コードのコメントは、「LockFree」リストについては、奇妙です:// " 残念ながら、他のスレッドがまだ古いキューに //参照を保持することが可能です。 // ActiveWritersカウントが0になるまで待つ必要があることを100%確実に確認する //現在ライターが存在する場合は、最初の書き込み側によって設定される //イベントを待つ // ActiveWritersを0に設定する必要がない場合は、待つ必要はありません。 " これは一種の"待機 "シンシナリゼーションのようです...私は間違っていますか? (このコメントは関数TMultiWriteSingleReadLockFreeQueue.Dequeue ) –

2

マルチプロデューサー/シングル・コンシューマ・キュー/ FIFOの場合、あなたは簡単に1 LockFreeを作ることができますSLISTや簡単なロックフリーLIFOスタックを使用して、あなたが行うことは、コンシューマにとって2番目の「プライベート」スタックを持つことです(簡単にするためのSLISTや選択した他のスタックモデルでも行うことができます)。プライベート・スタック。プライベートLIFOがexhastedされるたびに、あなたはフラッシュではなく、は(全体SLISTチェーンをつかんで)共有同時SLISTをオフにポップし、その後に次のプライベートスタックにアイテムをプッシュフラッシュさリストを歩いてください。

これは、シングルプロデューサ/シングルコンシューマとマルチプロデューサ/シングルコンシューマで動作します。

ただし、マルチプロデューサ/マルチコンシューマの場合は機能しません。

関連する問題