Semaphore, Mutex, Critical section, SpinLock, Event

Critical Section

Windows相关函数是EnterCriticalSection()和LeaveCriticalSection()，注意如果不Leave，其他需要这个critical section的线程都会被挂起。如果用MFC库，用CCriticalSection类的Lock()和UnLock()就可以了。有人用以下代码测量，得到的结果是1,000,000 uncontended acquires and releases, a mutex takes over one second. A critical section takes ~50 ms

HANDLE mutex = CreateMutex(NULL, FALSE, NULL);CRITICAL_SECTION critSec;InitializeCriticalSection(&critSec);LARGE_INTEGER freq;QueryPerformanceFrequency(&freq);LARGE_INTEGER start, end;// Force code into memory, so we don't see any effects of paging.EnterCriticalSection(&critSec);LeaveCriticalSection(&critSec);QueryPerformanceCounter(&start);for (int i = 0; i < 1000000; i++){    EnterCriticalSection(&critSec);    LeaveCriticalSection(&critSec);}QueryPerformanceCounter(&end);int totalTimeCS = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);// Force code into memory, so we don't see any effects of paging.WaitForSingleObject(mutex, INFINITE);ReleaseMutex(mutex);QueryPerformanceCounter(&start);for (int i = 0; i < 1000000; i++){    WaitForSingleObject(mutex, INFINITE);    ReleaseMutex(mutex);}QueryPerformanceCounter(&end);int totalTime = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);printf("Mutex: %d CritSec: %d/n", totalTime, totalTimeCS);

The 'fast' Windows equal of critical selection in Linux would be a futex, which stands for fast user space mutex. The difference between a futex and a mutex is that with a futex, the kernel only becomes involved when arbitration is required, so you save the overhead of talking to the kernel each time the atomic counter is modified. A futex can also be shared amongst processes, using the means you would employ to share a mutex.

Unfortunately, futexes can be very tricky to implement (PDF).

Mutex ("mutual exclusion" lock)

Mutex和critical section一样，用来保证同时只有一个线程进入某区域，通常用来实现对某单一资源的访问控制。Mutex可以设定time out，可以不像critical section一样死等。如果一个拥有Mutex的线程在返回之前没有调用ReleaseMutex()，那么这个Mutex就被舍弃了，但是当其他线程等待(WaitForSingleObject等)这个Mutex时，仍能返回，并得到一个WAIT_ABANDONED_0返回值。

A mutex (which stands for "mutual exclusion" lock) is a locking or synchronization object that allows multiple threads to synchronize access to shared resources. It is often used to ensure that shared variables are always seen by other threads in a consistent state.

In Windows, the mutexes are both named and un-named. The named mutex is shared between the threads of different process.

In Linux, the mutexes are shared only between the threads of the same process. To achieve the same functionality in Linux, a System V semaphore can be used (具体参考这篇文章).

Practially, CriticalSection is much faster when there's no actual blocking (due to reduction in user-kernel mode switches), and probably slower when there is blocking (due to more complex implementation). Additionally, since a Mutex is represented by a HANDLE, you can wait on a mutex with a timeout, or with several other handles. Neither option is available with a Critical Section. Mutexes can be named and shared between processes, while CriticalSections are restricted to the threads of a single process.

Semaphore

VxWorks没有Mutex, 它提供三种Semaphore: binary, counting, mutex. 相关API是semBCreate, semMCreate, semCCreate, semDelete, semTake, semGive, semFlush

taken a low priority task and the low priority task, its priority will be temporarily changed to the high priority task which is waiting.

Binary semaphore

Event

Event可以用来实现observer模式。创建一个Event，然后用WaitForSingleObject()挂起等待其它线程点亮(set)这个Event。我经常用的一个伎俩是在用户态创建一个Event的句柄，然后通过DeviceIoControl()把它传到驱动里面去，当驱动收到外部总线传来的数据包就点亮这个Event。Windows的API是CreateEvent（）     OpenEvent（）    SetEvent（）     WaitForSingleObject（） WaitForMultipleObjects（）。MFC库里有CEvent类。

Spin lock

spin lock是一个内核态概念。spin lock与semaphore的主要区别是spin lock是busy waiting，而semaphore是sleep。对于可以sleep的进程来说，busy waiting当然没有意义。对于单CPU的系统，busy waiting当然更没意义（没有CPU可以释放锁）。因此，只有多CPU的内核态非进程空间，才会用到spin lock。Linux kernel的spin lock在非SMP的情况下，只是关irq，没有别的操作，用于确保该段程序的运行不会被打断。其实也就是类似mutex的作用，串行化对 critical section的访问。但是mutex不能保护中断的打断，也不能在中断处理程序中被调用。而spin lock也一般没有必要用于可以sleep的进程空间。

临界区（Critical Section）、互斥量（Mutex）、信号量（Semaphore）、事件（Event）的区别

2013-09-05 10:56:40

临界区（Critical Section），互斥量（Mutex），信号量（Semaphores），事件（Event） 的区别

2013-04-06 19:26:39

【Win32多线程】同步机制(Critical section、Mutexes、Semaphore、Event Object)

2012-07-22 14:37:34

Mutex/Semphore/Binary Semphore的异同

2009-05-22 14:24:00

Mutex和Critical Section的异同点

2013-03-05 22:19:38

临界区(Critical section)与互斥量(Mutex)

2016-01-10 18:19:53

spinlock，mutex,semaphore，critical section的作用与区别

2014-10-13 09:49:06

Mutex, semaphore, spinlock的深度解析

2012-10-18 23:34:13

多线程之mutex、semaphore区别

2013-04-05 12:41:17

C++多线程之使用Mutex和Critical_Section

2013-11-28 13:54:19