浅谈C# ReaderWriterLock

开发 后端
这里介绍后来我干脆不用C# ReaderWriterLock了,直接换成了LockFree的方法。在C#中实现LockFree其实是很简单的,因为有了Garbage Collection。

前一阵在一个project中使用了C# ReaderWriterLock,发现了两个问题:

Performance非常差

UpgradeToWriterLock并不是atomic的从ReaderLock转换到WriterLock,而是等同于"lock.ReleaseReaderLock(); lock.AcquireWriterLock();".这样的semantics有一定的迷惑性,我开始的时候也认为这个operation是 atomic的,等出现bug并debug了很久才发现原来如此。不过经过认真的思考,发现这其实不是。NET designer的错,根本没办法把这个operation设计成atomic的。原因如下:

很多个thread同时acquire到了ReaderLock,

他们都call UpgradeToWriterLock,如果这个operation是atomic的,那么没有哪个thread能upgrade成功。

后来我干脆不用C# ReaderWriterLock了,直接换成了LockFree的方法。在C#中实现LockFree其实是很简单的,因为有了Garbage Collection,

code:

  1. class LockFreeDictionary<Key, Value>{  
  2. private Dictionary<Key, Value> m_dict = new Dictionary<Key, Value>();  
  3.  
  4. public Value Lookup(Key key){  
  5. return m_dict[key];  
  6. }  
  7.  
  8. public void Update(Key key, Value value){  
  9. Dictionary<Key, Value> newDict = null;  
  10. Dictionary<Key, Value> oldDict = null;  
  11. do{  
  12. oldDict = m_dict;  
  13. newnewDict = new Dictionary<Key, Value>(oldDict);  
  14. newDict[key] = value;  
  15. }  
  16. while (Interlocked.CompareExchange<Dictionary<Key, Value>>
    (ref m_dict, newDict, oldDict) != oldDict);  
  17. }  
  18. }  

第16行 ,保持参照原有Dictionary物件,

第17行,建造一个新的字典对象的基础上原有的物件。为oldDict ,这一步是只读的,而且不需要锁,

第18行,执行更新操作后,新建造的对象,

第19行,请尝试更换新的对象到原来的1 。如果返回值Interlocked.CompareExchange操作不等于oldDict ,这意味着在此做,而块executation ,有另一个线程改变m_dict 。在这种情况下,我们需要做更新一次。

换出的对象( oldDict )可以收集到的垃圾收集。

如果我们想用LockFree数据结构C++中,还有另一种技术称为危害指针。这是在IBM的研究论文。

不过不是什么情况都可以使用这种LockFreeDictionary的,,不然你会得到相反的效果(performance很差),这里的scenario是read非常多,write非常少。 不过这种情况也挺常见的。

这种方法的好处是在Lookup的时候没有任何lock,从而极大的提高了performance.(我的project里面比C# ReaderWriterLock提高了2000倍,)

对LockFree有研究的或者有兴趣的可以留言大家讨论讨论

【编辑推荐】

  1. C#跳跃语句学习经验
  2. 简单描述C#哈希值
  3. 如何用C#和ADO.NET访问
  4. C#建立Web Service
  5. 浅析C# 匿名方法
责任编辑:佚名 来源: 博客园
相关推荐

2011-09-21 10:56:31

C#结构

2009-08-19 17:12:18

C# Connecti

2009-08-12 11:24:25

C# String对象

2009-08-07 11:26:53

C#数组结构

2009-08-31 09:37:09

C# Employee

2009-08-25 16:16:43

C# oledbcon

2009-08-26 15:46:01

C#匿名类型

2009-08-20 10:24:52

C#开发WinForm

2009-08-06 15:30:23

C#类型系统

2009-08-26 13:15:38

C#选择控制

2009-08-14 17:58:05

C#接口方法

2009-09-02 15:41:21

C# HTTPWebR

2009-08-10 10:04:25

C#抽象类C#接口

2009-08-11 13:13:09

C#和Java比较

2009-09-02 16:23:27

C# Singleto

2009-08-19 17:45:26

C#使用GDI+

2009-08-10 14:55:04

C#定义Nullabl

2009-08-18 17:08:50

C#编写XML文档

2009-09-04 11:00:13

通过C#引用传递

2009-08-27 14:44:11

C# interfac
点赞
收藏

51CTO技术栈公众号