例子:记录线程调用顺序
#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 )
{
//如果不加临界区 vector.push_back操作可能中途被打断 出现错误
EnterCriticalSection(&testCS);
int i = (int)lpParam;
orderVec.push_back(i);
LeaveCriticalSection(&testCS);
return TRUE;
}
结果:
order of calling thread:0, 1, 2, 4, 5, 3, 7, 6, 8, 请按任意键继续. . .
InitializeCriticalSection function
初始化一个临界区对象
void WINAPI InitializeCriticalSection(
_Out_ LPCRITICAL_SECTION lpCriticalSection
);
参数
lpCriticalSection [out]
指向临界区对象的指针
注意
单进程中的线程可以使用临界界对象来解决青互斥同步问题。但不保证线程得到临界区对象的顺序,系统公平对待每个线程。进程负责为临界区对象分配内存。即定义一个类型为CRITICAL_SECTION变量。在使用临界区对象之前,进程中的线程必须初始化临界区对象。在临界区对象初始化之后,线程可以使用函数EnterCritical TryEnterCriticalSection或LeaveCriticalSection函数来互斥地访问共享资源。在不同进程中的线程同步,可以使用mutex对象。
临界区对象不能被移动,也不能被复制。进程不能修改临界区对象,但这是不符合逻辑的。只能使用临界区函数管理临界区对象。当你想结束一个临界区对象时,调用DeleteCriticalSection函数。
在重新初始化临界区对象之前,临界区对象必须被删除。初始化一个已经初始化的临界区对象,结果是未知的。