info = new SortedDictionary <string、string> ..。 スレッドA -------- info.Add( "abc"、 "def") スレッドB -------- 情報 |> Seq.iteri(fun ivalue->..。
iteri関数を使用する場合、readLockはどこに配置しますか?
info = new SortedDictionary <string、string> ..。 スレッドA -------- info.Add( "abc"、 "def") スレッドB -------- 情報 |> Seq.iteri(fun ivalue->..。
iteri関数を使用する場合、readLockはどこに配置しますか?
可変性の問題を回避し、SortedDictionary の代わりに不変の Map を使用することもできます。このように、反復はデータ構造の「スナップショット」で機能し、下から変更される心配はありません。次に、スナップショットの最初のグラブをロックするだけです。
例 (警告、これが実際にスレッドセーフかどうかはテストしていません!):
let mymap = ref Map<string,string>.Empty
let safefetch m = lock(m) (fun () -> !m)
let safeadd k v m = lock(m) (fun () -> m := Map.add k v !m)
mymap
|> safefetch
|> Map.iter ( fun k v -> printfn "%s: %s" k v )
mymap |> safeadd "test" "value"
Seq.iteri にロックを設定しても、F# では Seq が遅延するため、実際には意味がないように思われます。
ただし、シーケンスの反復中に辞書の追加要素が別のスレッドによって挿入されると、例外がスローされることに注意してください。それが怠惰な反復に対して完全に保証されているかどうかはわかりません。
現在の私の解決策(関数として)は次のとおりです。
(楽しい _ -> ロック情報 (楽しい _ -> 情報 |> Seq.iteri (fun ix -> ...)))
私自身の質問に答えてもよろしいと思います(私はここで初めてです)。