2013-02-01 17 views
6

私の状況は次のとおりです。複数のライター、1つのリーダー、コレクション

複数のスレッドは、同じコレクション(追加と追加範囲)に同時に書き込む必要があります。アイテムの順序は問題ではありません。 すべてのスレッドが完了して(結合)、メインスレッドに戻ったら、すべてのスレッドが完了しているので、実際のロックが不要なforeachスタイルですべての収集データを高速に読み取る必要があります。

「古い日」では、おそらくリスト上でこれに対してリーダーライターロックを使用していましたが、新しい並行コレクションでは、より良い代替手段がないのだろうかと思います。私は、ほとんどの並行コレクションが読者が並行スレッドにいると仮定しているように見えるのは分かりません。

+0

.Net 4.0以上を使用している場合。 ConcurrentBag はあなたの目的を解決するはずです。私はあなたが要素の順序と除去に気をつけなければ最高だと思う。 –

+0

私はそれを見てきましたが、コンカレントバッグのforeachは毎回の読み取りごとにロックペナルティを意味しませんでしたか?古いリーダーライターのロックをより効率的にするには? –

+0

@ハンスとフィリップリエック、あなたは絶対に正しいです。ここで並行コレクションを使用する理由はまったくありません。今私には明らかですが、私は多くのスレッドをスピンアップしなければならなかったという事実によって、盲目的になってしまいました。 Thxをクリアするため:)。 –

答えて

5

項目の順序は問題ありません。すべてのスレッドが完了してメインスレッドに戻ったら、すべての収集データを読み取る必要があります。

スレッドセーフなコレクションの要件はまったく指定されていません。 1つのコレクションを共有することには意味がありません。なぜなら、あなたが同時に書くことを読むことがないからです。注文は問題ではないので、すべての執筆が同じコレクションに起こることも重要ではありません。とにかく注文はランダムであるので、それは重要ではありません。

したがって、各スレッドには独自のコレクションを与えてください。ロックは必要ありません。その後、ロックを必要とせずに、それらを1つずつ繰り返します。

4

System.Collections.Concurrent.ConcurrentBagを試してください。コレクションの説明から

は、オブジェクトのスレッドセーフな、順不同コレクションを表します。

これは、複数のスレッドや重要な項目の順序を処理する基準を満たしていると思います。後でメインスレッドに戻ったときに、すぐにコレクションの繰り返し処理を行い、各項目を処理できます。

+0

私はそれを見てきましたが、コンカレントバッグの上のforeachは、すべてのシングルの読み込みにロックペナルティを含意していませんでしたか?古いリーダーライターのロックをより効率的にするには? –

+0

@ChristianMikkelsen .NET 4.0または.NET 4.5を実行していますか?次のブログ記事では、ConcurrentBagのパフォーマンスについて説明しています。http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0 –

+2

@ChristianMikkelsenいいえ、あなたは大丈夫です:ConcurrentBag。 GetEnumerator()はその時点でスナップショットを返し、コレクションをロックしません。参照:http://msdn.microsoft.com/en-us/library/dd381960.aspx – drch

6

System.Collections.Concurrentでコレクションを使用したいとは思われません。これらは、一般的に並行読み取りを可能にするために余分のオーバーヘッドを持ちます

多量の競合が発生している場合を除き、単純にList<T>をロックして追加するほうがよいでしょう。リストのサイズ変更に伴い、オーバーヘッドが少なくなりますが、それほど頻繁には発生しません。

しかし、私はおそらくこのような場合にはどうなるのかは、単にスレッドではなく、共有される1つあたりList<T>に追加され、そしていずれかの処理の最後にそれらをマージ、または単にのそれぞれにすべての要素を反復処理しますコレクション。

あなたはおそらくConcurrentBagを使用して、時に読み込まする準備ができて(ごとの読み取りのペナルティをバイパスして)、その上に.ToArray()またはGetEnumerator()を呼び出していますが、挿入の速度があなたの手動書き込みロックよりも少し遅くなることがあります可能性があり

簡単にはListです。それは実際に競争の量に依存します。 ConcurrentBagはパーティション化についてはかなり良いですが、あなたが指摘したように、並行読み取りに合わせてと書いてあります。

いつものように、あなたの特定の状況をベンチマークしてください!マルチスレッドのパフォーマンスは、実際の使用状況では多くのものに大きく依存しており、データの種類や挿入数などは劇的に変化します。

+0

ベンチマークの推奨事項。フィリップはそうです。実際のデータ/読み取り/書き込みがどのように動作するかを知りたいと思うでしょう。 –

+1

1つにつき1つのリストスレッドごとに+1。 – dtb

関連する問題