线程同步

线程同步

  • 1.基本的原子操作
    • 可借助Inerlocked类,无需锁定任何对象即可获取到正确结果,Inerlock提供了Increment、Decement和Add等基本数学操作的原子方法:Interlocked.Incement(ref _count)

  • 2.Mutex类同步两个单独的线程,Mutex是一种原始的同步方式,只对一个线程授予对共享资源的独占访问
    • 主程序启动时,var m = new MutexName(false,MutexName)定义指定名称的互斥量,innitialOwner标志为false
    • 具名的互斥量是全局的操作系统对象,务必正确关闭互斥量,最好使用using代码块包裹互斥对象
    • 可用于不同的程序中同步线程,可被推广到大量的使用场景中
  • 3.使用SemaphoreSlim类
    • static SemaphoreSlim _semaphore = new SemaphoreSlim(4);
      • 指定允许的并发线程数量
    • 当有一个线程完毕后,使用_semaphore.Release()发出信号完成工作
    • 混合模式:允许我们在等待时间很短的情况下无需使用上下文切换
  • 4.AutoResetEvent类
    • 借助此类可以从一个线程向另一个线程发送通知。内核时间模式,等待时间不能太长
    • AutoResetEvent在调用Set()把信号量释放后(信号量设置为True)然后自动返回终止状态(信号量为False)
  • 5.ManualResetEventSlim类
    • 混合模式
    • 在调用set后,需要手动调用ReSet()恢复到终止状态。
    • ManualResetSlim是AutoResetEvent的简化版本,是4.0新增的类,使用wait()方法阻止线程
  • 6.CountDownEvent
    • 如何使用CountdownEvent信号类来等待直到一定数量的操作完成
    • 定义最多能够进入关键代码的线程数:static CountdownEvent _countdown =new CountdownEvent(2);
    • 主要的两个方法:主线程中调用wait()等待、子线程中完毕后要调用Signal()发出信号表示事情做完,
    • 还可以动态的设计等待线程数量
  • 7.Barrier
    • 指定我们想要同步的两个线程,子线程在调用SinalAndWait方法后会执行一个回调函数,
  • 8.ReaderWriterLockSlim
    • 创建一个线程安全机制,在多线程中对一个集合进行读写操作,代表了一个管理资源访问的锁,允许多个线程同时读取,以及独占。
  • 9.SpinWait
    • 介绍不使用内核模式的方式来使线程等待,SpinWait是一个混合同步构造,被设计为使用用户模式等待一段时间然后切换到内核模式以节省CPU时间。
  • 简介
    • 当一个线程执行递增和递减操作时,其他线程需要依次等待,这就叫做线程同步
    • 多线程同时使用共享对象会产生竞争条件的问题
    • 同步线程使得对共享对象的操作能够以正确的顺序执行
  • 如何实现线程同步
    • 1.尽量避免使用共享对象,那么就无须进行线程同步,重新设计程序可以移除共享状态,从而去掉复杂的同步构造

      2.必须使用共享状态,就只使用原子操作:操作只占用一个量子的时间,一次就可以完成,所以只有当前操作完成之后,其他线程才能执行其他操作,因此无须实现其他线程等待当前操作完成,避免了使用锁,也排除了死锁

      3.内核模式:如果上述两种方法还是不行,那么就不得不使用不同的方式来协调线程,第一种方式:设置等待的线程为阻塞状态(:线程处于阻赛状态只会占用尽可能少的CPU时间,意味着将至少引入一次所谓的上下文切换(context switch)(:操作系统的线程调度器)),调度器会保存等待的线程状态,并切换到另一个线程,依次恢复等待的线程状态。这需要消耗相当多的资源。如果线程需要被挂起的很长的时间,这样做是值得的。这种方式简称为内核模式(kernel_mode),只有操作系统的内核才能阻止线程使用CPU时间。

      4.用户模式:如果线程只需要等待一小段时间,最好只是简单的等待,而不用将线程切换到阻塞状态,虽然线程切换到阻塞状态,虽然线程等待会浪费CPU时间,但我们节省了上下文切换耗费的CPU时间,模式为:用户模式(user_mode)。如果线程需要等待较长时间会浪费大量时间

      5.混合模式(hybrid):合理的使用内核模式和混合模式,尝试使用用户模式等待,如果线程等待了足够长的时间,则会切换到阻塞状态以节省CPU资源 

原文地址:https://www.cnblogs.com/bigbear1385/p/5107539.html