使用readlock和writelock同步SortedDictionary.iteri

时间:2009-07-19 15:48:56

标签: f# synchronization locking sorteddictionary

let info = new SortedDictionary<string, string>

...

Thread A
--------
info.Add("abc", "def")

Thread B
--------
info
|> Seq.iteri (fun i value ->  ...

当我使用iteri函数时,我在哪里放置readLock?

2 个答案:

答案 0 :(得分:1)

您可能只想解决可变性问题,并使用不可变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"

答案 1 :(得分:0)

经过一番思考后,似乎锁定Seq.iteri实际上没有任何意义,因为Seq在F#中是懒惰的。

然而,值得注意的是,在序列迭代期间,当另一个线程插入字典的其他元素时,会抛出异常。不确定是否完全保证了懒惰迭代。

我现在的解决方案(作为一项功能)是:

(fun _ -> 
   lock info (fun _ ->
                info
                |> Seq.iteri (fun i x -> ...)))

我希望可以回答我自己的问题(我是新来的)。