临界区只有4个函数:
函数功能:初始化
void InitializeCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);
函数说明:定义关键段变量后必须先初始化。
函数功能:销毁
void DeleteCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);
函数说明:用完之后记得销毁。
函数功能:进入临界区
void EnterCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);
函数说明:系统保证各线程互斥的进入临界区。
由于线程切换到等待状态开销较大,所以windows旋转让线程处于一个循环锁中循环,一段时间后才切换称等待。
函数功能:离开临界区
void LeaveCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);
临界区可以用于线程间的互斥,但是不能用于同步,由于临界区是指进入 这个临界区后,线程才可以进行下一部操作,如果理解区中已有其他线程,则不可以进入新的线程,线程要等待临界区中已有线程离开。而主线程拥有对所有数据的访问权限,导致主线程可以在子线程之前修改参数。
CRITICAL_SECTION cs;
typedef struct param{
int a;
bool b;
double c;
string d;
};
unsigned int __stdcall threadfun1(LPVOID p){
Sleep(100);
EnterCriticalSection(&cs);
param* funparam = (param*) p;
cout<<"fun1 running:"<<funparam->d<<endl;
funparam->c *= funparam->a;
cout<<"ans:"<<funparam->c<<endl;
LeaveCriticalSection(&cs);
return 0;
}
DWORD __stdcall threadfun2(LPVOID p){
Sleep(100);
EnterCriticalSection(&cs);
param* funparam = (param*) p;
cout<<"fun2 running:"<<funparam->d<<endl;
funparam->c /= funparam->a;
cout<<"ans:"<<funparam->c<<endl;
LeaveCriticalSection(&cs);
return 0;
}
int main(){
param p={5,true,9.995,"hello world"};
InitializeCriticalSection(&cs);
HANDLE newthread1 = (HANDLE)_beginthreadex(NULL,0,threadfun1,&p,0,NULL);
HANDLE newthread2 = CreateThread(NULL,0,threadfun2,&p,0,NULL);
WaitForSingleObject(newthread2,INFINITE);
WaitForSingleObject(newthread1,INFINITE);
DeleteCriticalSection(&cs);
临界区实现的是互斥,临界区中有全部的系统资源的控制权,当一个线程进入临界区后,便获得了这些资源,设置一个临界区,通过临界区中只能有一个线程,使资源也只有一个线程在一个时刻可以访问,即互斥。