溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

VC++線程同步(三) 臨界區(qū)使用例子

發(fā)布時(shí)間:2020-04-07 20:55:12 來源:網(wǎng)絡(luò) 閱讀:1142 作者:超級(jí)極客 欄目:編程語言

                    臨界區(qū)(Crtical Section)同步對(duì)象


用戶模式下的同步對(duì)象

Win32中,最容易使用的一個(gè)同步機(jī)制就是(關(guān)鍵段)Critical Section, 某些共享資源具有互斥性,也就是它要求被互斥地使用,他也是用于資源的互斥, 在大部分情況下,使用臨界區(qū)替換Mutex(Mutex是內(nèi)核模式下的同步對(duì)象)。

局限性:他只能用于同步單個(gè)進(jìn)程中的線程。


在任何同步機(jī)制當(dāng)中,無論是哪個(gè)操作系統(tǒng)下,都不要

長時(shí)間的鎖住資源,如果一直鎖定資源,就會(huì)一致阻止其他線程的執(zhí)行,

使整個(gè)程序,處于完全停止的狀態(tài)。

不要在critical section中調(diào)用Sleep或任何Wait等待之類的api函數(shù).

、、、  臨界區(qū)很容器造成資源死鎖.



                        相關(guān)Api函數(shù)



1初始化一個(gè)臨界區(qū)

InitializeCriticalSection函數(shù)

VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection //critical section);

lpCriticalSection  臨界資源對(duì)象指針





2釋放一個(gè)臨界區(qū)對(duì)象來釋放所有的資源,使得不再擁有這個(gè)對(duì)象

void DeleteCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

)

lpCriticalSection 指向一個(gè)不再需要的CRITICAL_SECTION變量





3 進(jìn)入臨界區(qū),也就意味著我進(jìn)行加鎖,在他之后已經(jīng)加鎖了

void EnterCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

)

lpCriticalSection  臨界區(qū)資源對(duì)象指針





4 離開臨界區(qū) ,也就意味著解鎖,所有的資源都處于安全狀態(tài)

void LeaveCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

)

lpCriticalSection  臨界區(qū)資源對(duì)象指針





              臨界區(qū)和Mutex的區(qū)別


臨界區(qū)是用戶模式下的,優(yōu)點(diǎn)是速度快,缺點(diǎn)是容易線程死鎖。他

不能跨進(jìn)程,而Mutex內(nèi)核模式下的同步對(duì)象是可以進(jìn)行,安全的跨進(jìn)程操作,但是他相對(duì)與用戶模式,速度比較慢,  因此正常情況下,使用

臨界區(qū)。

             

                臨界區(qū)         Mutex

1  速度:         快              慢

2  跨進(jìn)程:     不可以           可以

3  聲明:    CRITICAL_SECTION cs   HANDLE hmtx;

4  初始化: InitializeCriticalSection(&cs) hmtx = CreateMutex(NULL,FALSE,NULL);

5  清理:  CloseHandle            DeleteCriticalSection

6 無限的等待:EnterCriticalSection(&cs)   WaitForSingleObject(,INFINITE).  

7 不等待(不阻塞)TryEnterCriticalSection(&cs) WaitForSingleObject(,0);  

8 任意時(shí)間 臨界區(qū)是沒有這個(gè)功能   WaitForSingleObject(,1000)

9 釋放(解鎖)LeaveCriticalSection(&cs)

ReleaseMutex(.);





                        臨界區(qū)使用實(shí)例


首先定義一個(gè)全局的CRITICAL_SECTION g_cs;

在Create里初始化臨界區(qū)

case WM_CREATE:
{
int cyChar = HIWORD(GetDialogBaseUnits());
thrParams2.hwnd = hWnd;
thrParams2.cyChar = cyChar;
//初始化臨界區(qū)
InitializeCriticalSection(&g_cs);
//創(chuàng)建線程
HANDLE handleTicket1 = CreateThread(NULL, 0, ThrCalcProc1, &thrParams2, 0, NULL);
HANDLE handleTicket2 = CreateThread(NULL, 0, ThrCalcPro2, &thrParams2, 0, NULL);
//關(guān)閉線程句柄
CloseHandle(handleTicket1);
CloseHandle(handleTicket2);
}

case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO:  在此添加任意繪圖代碼...
TextOut(hdc, clientCX / 4, 0, _T("使用臨界區(qū)實(shí)現(xiàn)同步"), lstrlen(_T("使用臨界區(qū)實(shí)現(xiàn)同步")));
EndPaint(hWnd, &ps);
break;

case WM_DESTROY:

//清理臨界區(qū)的指針內(nèi)存
DeleteCriticalSection(&g_cs);
PostQuitMessage(0);
break;



然后觀察線程的回調(diào)函數(shù)

DWORD WINAPI ThrCalcProc1(LPVOID lp)
{
//獲得結(jié)構(gòu)體指針
PPARAMS param2 = static_cast<PPARAMS>(lp);
//生成隨機(jī)數(shù)種子
srand(time(NULL));
TCHAR szBuf[50] = { 0 };
HDC hdc;
while (true)
{
//休眠一秒  不要在進(jìn)入臨界區(qū) 休眠
Sleep(1000);
//進(jìn)入臨界區(qū) (加鎖)
EnterCriticalSection(&g_cs);
//g_subjectNum是數(shù)字題的數(shù)量
if (g_subjectNum > 0)
{
//檢查文本是否超出窗口顯示范圍,如果是就刷新窗口,并重新設(shè)置iLine值
//g_iLine2 = CheckTextRange(param2->hwnd, param2->cyChar, param2->cyChar,g_iLine2);
//隨機(jī)產(chǎn)生兩個(gè)數(shù)
int lval = rand() % 100;
int rval = rand() % 100;
int res = lval + rval;
//把解鎖 繪制到窗口上
wsprintf(szBuf, _T("線程1第%d題:%d + %d = %d"),g_subjectNum--,lval,rval,res);
hdc = GetDC(param2->hwnd);
TextOut(hdc, 0, g_iLine2*param2->cyChar,
szBuf, lstrlen(szBuf));
ReleaseDC(param2->hwnd,hdc);
g_iLine2++;
//解鎖
LeaveCriticalSection(&g_cs);
}
else
{ 
//解鎖
LeaveCriticalSection(&g_cs);
break;
}
}
return 0;
}



VC++線程同步(三) 臨界區(qū)使用例子




代碼下載地址:http://down.51cto.com/data/2329647







向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI