Critical Section Object From MSDN
Critical Section Objects
A critical section object provides synchronization similar to that provided by a mutex object, except that a critical section can be used only by the threads of a single process.
Event, mutex, and semaphore objects can also be used in a single-process application,
but critical section objects provide a slightly faster, more efficient mechanism for mutual-exclusion synchronization (a processor-specific test and set instruction).
Like a mutex object, a critical section object can be owned by only one thread at a time, which makes it useful for protecting a shared resource from simultaneous access.
Unlike a mutex object, there is no way to tell whether a critical section has been abandoned.
Critical Section Object(临界区对象)提供一种同步机制.类似于mutex object. 但是Critical Section Object 对象仅仅只能在单进程中使用.
Event,Mutex and semaphore object 也是只能在单进程程序中使用.
但是Critical Section Object 提供一种轻量级 ,快速,高效的机制来同步并发执行.
类型于Mutex Object ,Critical Section Object 同一时间仅仅能被一个线程拥有.对于共享资源的并发访问非常有用.
与Mutex Object 不同的是,不存在测试一个Critical Section Object 是否被抛弃.
Starting with Windows Server 2003 with Service Pack 1 (SP1), threads waiting on a critical section do not acquire the critical section on a first-come, first-serve basis.
This change increases performance significantly for most code.
However, some applications depend on first-in, first-out (FIFO) ordering and may perform poorly or not at all on current versions of Windows .
(for example, applications that have been using critical sections as a rate-limiter).
从Windows Server2003 开始,线程获取Critical Section Object 不需要先到先得,这个改变大大提高代码小龙.
然后,一些应用程序依赖先进先出FIFO顺序来执行效率很低.
To ensure that your code continues to work correctly, you may need to add an additional level of synchronization.
For example, suppose you have a producer thread and a consumer thread that are using a critical section object to synchronize their work.
Create two event objects, one for each thread to use to signal that it is ready for the other thread to proceed.
The consumer thread will wait for the producer to signal its event before entering the critical section, and the producer thread will wait for the consumer thread to signal its event before entering the critical section.
After each thread leaves the critical section, it signals its event to release the other thread.
Windows Server 2003 and Windows XP:
Threads that are waiting on a critical section are added to a wait queue;
they are woken and generally acquire the critical section in the order in which they were added to the queue.
However, if threads are added to this queue at a fast enough rate, performance can be degraded because of the time it takes to awaken each waiting thread.
在Windows Server2003 和Windows XP:
等待Critical Section Object 对象的线程都被加入到等待队列.
然后,线程被唤醒是按照在等待队列中的顺序进行.然而,如果现在被加入到队列中的速度足够快,在队伍中排队的时间远远小于线程被唤醒的时间.
测试代码:
#include <windows.h>
#include <iostream>
#include <vector>
using namespace std;
#define THREADCOUNT 9
CRITICAL_SECTION testCS;
DWORD WINAPI ThreadFunc( LPVOID );
std::vector<int> orderVec;
//记录线程调用顺序
int main( void )
{
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
int i;
InitializeCriticalSection(&testCS);
// Create worker threads
for( i=0; i < THREADCOUNT; i++ )
{
aThread[i] = CreateThread(
NULL, // default security attributes
0, // default stack size
ThreadFunc, //(LPTHREAD_START_ROUTINE)
(LPVOID)i, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
}
Sleep(100);
for( i=0; i < THREADCOUNT; i++ )
CloseHandle(aThread[i]);
int count = orderVec.size();
cout << " order of calling thread:";
for (int i=0; i<count; ++i)
{
cout << orderVec[i] << ", ";
}
DeleteCriticalSection(&testCS);
system("pause");
return 0;
}
DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
//所有访问orderVec 对象的线程,都将在Critical Section Object 按照FIFO顺序排队.
//当不存在临界区时,orderVec顺序将乱序.
EnterCriticalSection(&testCS);
int i = (int)lpParam;
orderVec.push_back(i);
orderVec.push_back(i);
orderVec.push_back(i);
LeaveCriticalSection(&testCS);
return TRUE;
}
测试结果: