天天看点

c++ 多线程 临界区

临界区只有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);
           

临界区实现的是互斥,临界区中有全部的系统资源的控制权,当一个线程进入临界区后,便获得了这些资源,设置一个临界区,通过临界区中只能有一个线程,使资源也只有一个线程在一个时刻可以访问,即互斥。