let info = new SortedDictionary<string, string> ... Thread A -------- info.Add("abc", "def") Thread B -------- info |> Seq.iteri (fun i value -> ...
當我使用iteri函數時,我在哪裏放置readLock?使用readlock和writelock同步SortedDictionary.iteri
let info = new SortedDictionary<string, string> ... Thread A -------- info.Add("abc", "def") Thread B -------- info |> Seq.iteri (fun i value -> ...
當我使用iteri函數時,我在哪裏放置readLock?使用readlock和writelock同步SortedDictionary.iteri
您可能想要簡單介紹可變性問題,並使用不可變Map來代替SortedDictionary。這樣,您的迭代就可以在數據結構的「快照」上進行工作,而不用擔心它會從您的下面變出。然後,你只需要鎖定你的初始抓取快照。
例如(警告,沒有測試,看看這實際上是線程安全的!):
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#中是懶惰的。
但是有趣的是,在序列迭代過程中,當另一個線程插入字典的其他元素時會引發異常。不確定這是否完全保證一個懶惰的迭代。
我的解決方案(如函數)現在的問題是:
(fun _ -> lock info (fun _ -> info |> Seq.iteri (fun i x -> ...)))
我希望它是確定回答我的問題(我是新來的)。
在Map.iter啓動之前不會釋放在安全提取中設置的鎖嗎? – Moonlight 2009-07-19 17:41:03