对于windows,临界区(critical sections )比 互斥量(mutexes) 更加轻量级(lighter-weight)。
互斥量可以在进程之间共享,但总是会导致对内核的系统调用,这会带来一些开销。
当一个进程进入临界区,没有其他进程可被允许在临界区执行,即没有两个进程可同时在临界区内执行。其优点是在多进程抢占的情况下只能切换到内核模式。通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
下面是一段简单的代码来比较临界区和互斥量。进行1000000次的非竞争访问和释放,互斥量需要超过1s,而临界区需要大概50ms.
HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
CRITICAL_SECTION critSec;
InitializeCriticalSection(&critSec);
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;
// 将代码强制载入内存,这样消除分页对实验带来的影响。
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);
// 将代码强制载入内存,这样消除分页对实验带来的影响。
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);
参考:
stackoverflow : What is the difference between mutex and critical section?