CLR via c# 笔记:原始同步结构

在多线程程序中(CPU bound或IO bound类型),不可避免地要考虑同步问题。同步是多线程里最容易出错的地方,你必须保证所有多线程共享的对象在任何使用的地方都考虑同步了。另同步也是一个影响性能的地方,锁定和解锁需要花费一定的资源和时间。如果线程被block了,可能会导致线程池认为CPU空闲了而去创造更多的线程来使得CPU繁忙,这会导致新的问题,比如大量线程block的时候,线程创建越来越多,占用更多的资源,且如果block的线程突然大量被同时唤醒,使得线程量大大多余CPU核数,造成频繁切换。
    基于上面理由,尽可能在程序设计的时候减少使用同步,减少对象在线程间共享。多线程共享只读对象不需要同步
这里主要介绍原始同步对象,下一篇介绍高级同步对象及其原理和使用
 

FCL里的约定

FCL里的static函数永远是线程安全的,比如Math的Max,Console,ThreadPool.QueueWorkItem


原始用户模式同步对象和内核模式同步对象

无论在何时,应该尽量优先考虑使用用户态的同步对象

用户态的同步操作是CPU的特殊指令支持,比内核态的同步快,但操作系统不会感知,这使得同步等待时会占用CPU

内核态的同步操作会使得线程从用户态切到内核态然后切回

两种同步都有利弊,理想情况是在短时间占有或没有竞争的情况用用户态同步,在长时间获取不到资源的时候用内核态同步,这种是可以实现的,在FCL里已经为我们提供了,详情见下一篇。

用户模式同步对象    

CLR 保证对以下类型的读写是原子的:Boolean, Char, Byte, Int16, Int32, IntPtr, Single 注意没有Int64和Double

Volatile

保证对基本类型读写的原子性,保证读写的时机性。由于编译器的优化,有可能交换读取变量的顺序,有肯能在编译期间认为变量不会改变而将一些看似确定的代码优化(比如觉得loop不会发生而直接删除)。

Volatile.Read保证read之前的操作都已完成,Volatile.Write保证write之后的操作一定在这之后。

c#支持在Field上标注Volatile,这样所有的读写地方自动运用Volatile

InterLocked 对象

InterLocked操作可以针对Int32,Int64,Object,IntPtr,Single,Double

InterLocked操作是原子的,针对Int32有如下方法Increment, Decrement, Add, Exchange, CompareExchange

一个自旋锁的实现

自旋锁:在未得到锁的时候不是block线程,而是循环获取锁,直到获取成功,会一直占用CPU。对于锁占用时间很短的情况很有用,因为不会有用户态到内核态的切换开销,也不会让线程池频繁创建线程。

代码参考如下:

 public void Enter() {       
while (true) {          // Always set resource to in-use 
         // When this thread changes it from not in-use, return          
if (Interlocked.Exchange(ref m_ResourceInUse, 1) == 0) return;          // Black magic goes here...       
}    
}

上面程序有个缺陷,没有获取到锁的时候,CPU一直占用,这使得在单CPU或多线程单CPU(Hyperthreaded CPU)无法切换到别的线程,从而锁一直无法释放。解决的办法是在循环的时候加一些Black magic,如Sleep,Yield(Sleep(0) 和Sleep(1) 切换, 0强制windows重新调度,包括自己,1使得重新调度的时候去除自己),SpinWait(Hperthread CPU switch to another thread)

用自旋锁来锁定任意处理

(仅限于上面interlock支持的类型)

代码进入的时候,取出需要lock的对象值,然后做处理,处理结束的时候调用compareexchange来确保lock当前的值还是最初获取的值,如果不是,则返回循环重新做一次处理

内核态锁

内核态锁的使用场景

内核锁的性能会比用户锁差约2个数量级

跨appdomain的线程同步,跨进程的线程同步,跨语言的线程同步,阻塞时间比较久,不希望浪费CPU的

内核同步对象

自动重置事件,手动重置事件,信号量,Mutex

猜你喜欢

转载自blog.csdn.net/xuefeiliuyuxiu/article/details/81057775