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

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

東河網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、響應式網(wǎng)站建設等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)公司于2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經驗和運維經驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選成都創(chuàng)新互聯(lián)公司。

用戶模式下的同步對象

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

局限性:他只能用于同步單個進程中的線程。

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

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

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

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

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

                        相關Api函數(shù)

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

InitializeCriticalSection函數(shù)

VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection //critical section);

lpCriticalSection  臨界資源對象指針

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

void DeleteCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

)

lpCriticalSection 指向一個不再需要的CRITICAL_SECTION變量

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

void EnterCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

)

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

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

void LeaveCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

)

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

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

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

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

臨界區(qū)。

             

                臨界區(qū)         Mutex

1  速度:         快              慢

2  跨進程:     不可以           可以

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 任意時間 臨界區(qū)是沒有這個功能   WaitForSingleObject(,1000)

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

ReleaseMutex(.);

                        臨界區(qū)使用實例

首先定義一個全局的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);
//關閉線程句柄
CloseHandle(handleTicket1);
CloseHandle(handleTicket2);
}

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

case WM_DESTROY:

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

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

DWORD WINAPI ThrCalcProc1(LPVOID lp)
{
//獲得結構體指針
PPARAMS param2 = static_cast<PPARAMS>(lp);
//生成隨機數(shù)種子
srand(time(NULL));
TCHAR szBuf[50] = { 0 };
HDC hdc;
while (true)
{
//休眠一秒  不要在進入臨界區(qū) 休眠
Sleep(1000);
//進入臨界區(qū) (加鎖)
EnterCriticalSection(&g_cs);
//g_subjectNum是數(shù)字題的數(shù)量
if (g_subjectNum > 0)
{
//檢查文本是否超出窗口顯示范圍,如果是就刷新窗口,并重新設置iLine值
//g_iLine2 = CheckTextRange(param2->hwnd, param2->cyChar, param2->cyChar,g_iLine2);
//隨機產生兩個數(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

網(wǎng)站名稱:VC++線程同步(三)臨界區(qū)使用例子
本文鏈接:http://bm7419.com/article34/gipgse.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供App開發(fā)網(wǎng)站導航、微信小程序、外貿建站網(wǎng)站建設、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站