我如何选择Semaphore和SemaphoreSlim?

时间:2010-11-11 12:43:23

标签: c# multithreading semaphore

他们的公共界面看似相似。 documentation表示SemaphoreSlim是一种轻量级选择,并且不使用Windows内核信号量。 This resource表示SemaphoreSlim要快得多。在什么情况下,SemaphoreSlim对信号量更有意义,反之亦然?

5 个答案:

答案 0 :(得分:58)

一个区别是SemaphoreSlim不允许命名信号量,它可以是系统范围的。这意味着SemaphoreSlim不能用于跨进程同步。

The MSDN documentation还表示当“等待时间预计非常短”时应该使用SemSlim。这通常与瘦身版本在大多数折衷方案中更轻巧的想法相吻合。

答案 1 :(得分:16)

The MSDN documentation描述了差异。

用一句话说:

  • SemaphoreSlim类表示一个轻量级,快速的信号量,当等待时间预计非常短时,可用于在单个进程内等待。

答案 2 :(得分:10)

SemaphoreSlim基于SpinWait和Monitor,因此等待获取锁的线程正在燃烧CPU周期一段时间,希望在屈服于另一个线程之前获取锁。如果没有发生这种情况,那么一旦操作系统再次调度该线程,线程就会让系统切换上下文并再次尝试(通过刻录一些CPU周期)。等待很长时间,这种模式可能会耗费大量的CPU周期。因此,这种实现的最佳情况是大部分时间没有等待时间,您几乎可以立即获得锁定。

Semaphore依赖于OS内核中的实现,因此每次获取锁时,都会花费相当多的CPU周期,但在此之后,线程会根据需要长时间休眠以获得锁定。

答案 3 :(得分:8)

关于"短时间"争议:

至少SemaphoreSlim MSDN documentation表示

  

SemaphoreSlim类是推荐的单个应用程序内同步信号量。

<备注部分中的

。同样的部分也讲述了Semaphore和SemaphoreSlim之间的主要区别:

  

SemaphoreSlim是Semaphore类的轻量级替代品,它不使用Windows内核信号量。与Semaphore类不同,SemaphoreSlim类不支持命名系统信号量。您只能将其用作本地信号量。

答案 4 :(得分:0)

我查看了源代码here,这就是我想出的:

  1. Semaphore和SemaphoreSlim都来自WaitHandle,它在内部使用Win32原生句柄。这就是你需要Dispose()的原因。所以Slim是轻量级的概念是可疑的。

  2. SemaphoreSlim在内部使用SpinWait,而Semaphore则不在。这告诉我,在预计等待时间很长的情况下,信号量应该做得更好,至少在它不会扼杀你的CPU的意义上。