IList を実装するロックフリーでスレッドセーフなデータ構造はありますか?
当然のことながら、ロックフリーとは、.NET でロック プリミティブを使用せず、インターロック操作/アトミック操作を使用してスレッド セーフを実現する実装を意味します...どうやら並行データ構造の下にはありません...
浮いてるの見たことある人いる?
私は、 LockFreeVector と呼ばれるamino-cbbsに実装されたJavaを見てきましたが、これまでのところ.NET用のものはありません。何か案は?
そうですね、そのようなクラスはどこにも見つかりませんでした。だから私はそれにショットを与えました。
ConcurrentList<T>
私のクラスのソースコードはGitHubで入手できます。
これはロックフリーでスレッドセーフであり(私の単体テストに基づくと思いIList<T>
ます)、を実装します。
、/ 、、またはをサポートしていません。Insert
RemoveAt
Remove
Clear
私の実装(私が独自に思いついたもの)が、ソフトウェアの世界で尊敬されている人々によって公開されたデータ構造の実装と非常に似ていることを発見してうれしく思いました。
実装自体のかなり簡単な議論については、それについての私の最近のブログ投稿を参照してください。
現時点では、それはまったく文書化されていません。これは、コードの一部がいかに「トリッキー」であるかを考えると、ちょっと悪いです:(
そして、ぜひ、バグやその他の問題を調べて見つけたら、新しいものをリッピングしてください。
とにかく、それをチェックするのはあなたの時間の価値があるかもしれません。もしそうなら、あなたの考えを教えてください。
Parallel.For
ホールメソッドとParallel.ForEach
クラスメソッドが原因で、IList を実装する ConcurrentList が Collections.Concurrent 名前空間にない可能性があります。リストをすばやく列挙し、そのアイテムに対してアクションを実行するために、それらを使用して任意のリストを同時実行として処理できると言えます。
おそらく提供しないことConcurrentList
で、Parralel.For が役に立たない場合は、IList ではなく、スタックやキュー、さらにはバッグやディクショナリなどの他の種類のコレクションを使用する必要があると考えていたのかもしれません。
マルチスレッド条件下でインデックス可能なコレクションを処理しなければならないことは、非常にエラーが発生しやすく、悪い設計のように聞こえるため、この設計に同意します。複数のリーダーが存在するような状況で、いつでもコレクションを変更でき、インデックスが無効になる場合、アイテムのインデックスを知る目的は何ですか-ライターは、キューまたはスタックが一般的に最適なコレクションになることは明らかです。バッグもいいかも。コレクションにアイテムを追加してもインデックスが無効にならないため、ディクショナリも使用できます。リストへの並列アクセスが必要な場合は、Parralel.For
メソッドを取得します
私が本当に奇妙だと思うもの - http://msdn.microsoft.com/en-us/library/dd381935.aspxここで ConcurrentLinkedList クラスについて読むことができますが、 System.dll で見つけることができません。 Bag と BlockingCollection しかありません。
また、少なくとも 95% の確率で、あなたの問題について 2 つのうちのいずれかが真実であると言えます。
また、ConcurrentList を提供しないことで、問題を解決するために誤って ConcurrentList を選択する開発者が多くのエラーを犯すのを防ぎ、開発者に既存の Concurrent コレクションの使用を強いる多くの時間を節約したとも言えます。
IList<T>
マルチスレッド環境でランダム アクセス ( で示される) がどのように機能するかを考えてみてください。追加と削除がアトミックであっても、スレッド 2 が取得しようとしていたインデックスでスレッド 1 がアイテムを削除することを妨げないため、不変でなければ実際には何もできません。そのため、SyncRoot は .NET 2.0 以降ではなくなりました。