天天看點

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);
           

臨界區實作的是互斥,臨界區中有全部的系統資源的控制權,當一個線程進入臨界區後,便獲得了這些資源,設定一個臨界區,通過臨界區中隻能有一個線程,使資源也隻有一個線程在一個時刻可以通路,即互斥。