How do I choose between Semaphore and SemaphoreSli

2019-01-21 21:34发布

问题:

Their public interfaces appear similar. The documentation states that the SemaphoreSlim is a lightweight alternative and doesn't use Windows Kernel semaphores. This resource states that the SemaphoreSlim is much faster. In what situations does the SemaphoreSlim make more sense over the Semaphore and vice versa?

回答1:

One difference is that SemaphoreSlim does not permit named semaphores, which can be system-wide. This would mean that a SemaphoreSlim could not be used for cross-process synchronization.

The MSDN documentation also indicates that SemSlim should be used when "wait times are expected to be very short". That would usually dovetail nicely with the idea that the slim version is more lightweight for most of the trade offs.



回答2:

The MSDN documentation describes the difference.

In one sentence:

  • The SemaphoreSlim class represents a lightweight, fast semaphore that can be used for waiting within a single process when wait times are expected to be very short.


回答3:

Regarding "short times" controversy:

At least SemaphoreSlim MSDN documentation states that

The SemaphoreSlim class is the recommended semaphore for synchronization within a single app.

in Remarks section. Same section also tells the main difference between Semaphore and SemaphoreSlim:

The SemaphoreSlim is a lightweight alternative to the Semaphore class that doesn't use Windows kernel semaphores. Unlike the Semaphore class, the SemaphoreSlim class doesn’t support named system semaphores. You can use it as a local semaphore only.



回答4:

SemaphoreSlim is based on SpinWait and Monitor, so the thread that waits to acquire the lock is burning CPU cycles for some time in hope to acquire the lock prior to yielding to another thread. If that does not happen, then the threads lets the systems to switch context and tries again (by burning some CPU cycles) once the OS schedules that thread again. With long waits this pattern can burn through a substantial amount of CPU cycles. So the best case scenario for such implementation is when most of the time there is no wait time and you can almost instantly acquire the lock.

Semaphore relies on the implementation in OS kernel, so every time when you acquire the lock, you spend quite a lot of CPU cycles, but after that the thread simply sleeps for as long as necessary to get the lock.



回答5:

I looked at the source code here and this is what I came up with:

  1. Both Semaphore and SemaphoreSlim derive from WaitHandle which internally uses Win32 native handle. Which is why you need to Dispose() both. So the notion that Slim is lightweight is suspect.

  2. SemaphoreSlim uses SpinWait internally while Semaphore does not. That tells me that in cases where the wait is expected to be long, Semaphore should do better at least in the sense that it will not choke out your CPU.