线程,同步构造

基元同步构造

在介绍了线程的基本概念和限制的异步操作之后,提出多线程,线程池的概念,就不得不提到线程安全、基元用户模式和基元内核模式。

基元 是指可以在代码中使用的最简单的构造。应尽量使用基元用户模式构造,它们的速度要显著快于内核模式的构造。这是因为它们使用了特殊的CPU指令来协调线程。这意味着协调是在硬件中发生的,所以才这么快,所以也就意味着OS就检测不到线程在用户模式构造堵塞了。

 

从脑图中可以看出,按模式划分的三种模式:用户模式、内核模式、混合模式。按方式划分:阻塞、非阻塞、锁构造。

由于模式转换会带来巨大的性能损失,线程占有锁的时间通常都很短。有的锁限制只能由获得锁的线程释放锁,有的锁允许当前拥有它的线程递归地拥有锁。

混合模式的构造提供了用户模式所具有的性能优势。多个线程竞争一个构造时,混合构造通过基元内核模式的构造来提供不自旋的优势。

FCL的混合构造

  1. Monitor类和同步块
    Monitor提供了自旋、线程所有权和递归的互斥锁,内置关键字lock支持它。
 

一个对象在构造时,它的同步块索引初始化为-1,表明不引用任何同步块。然后调用Enter时,CLR在数组中找到一个空白同步块,并设置对象的同步块索引,让它引用该同步块。当Exit时,检查是否有其他任何线程正在等待使用对象的同步块,没有就设置回-1。

  1. Barrier 类
  2. ReaderWriterLockSlim 类
  3. SemaphoreSlim
  4. System.Collections.Concurrent
  5. 双检锁

小结

代码尽量不要阻塞任何线程,执行异步计算或者I/O操作时候,将数据从一个线程交给另一个线程时候,应避免多个线程同时访问数据。同时访问数据的时候,应使用Volatile和Interlocked的方法,因为他们速度很快,而且不阻塞线程。
或者使用异步的同步构造来防止长时间占有锁,每个任务都关连一个或者多个连续任务,操作完成后,任务在线程池上继续执行,避免阻塞过久。对于I/O限制的操作,应当调用XxxAsync来完成操作。

posted @ 2019-11-30 22:38  米莱Milai  阅读(204)  评论(0编辑  收藏  举报