十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
臨界區(qū)(Crtical Section)同步對象
東河網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應式網(wǎng)站建設(shè)等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)公司于2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
用戶模式下的同步對象
Win32中,最容易使用的一個同步機制就是(關(guān)鍵段)Critical Section, 某些共享資源具有互斥性,也就是它要求被互斥地使用,他也是用于資源的互斥, 在大部分情況下,使用臨界區(qū)替換Mutex(Mutex是內(nèi)核模式下的同步對象)。
局限性:他只能用于同步單個進程中的線程。
在任何同步機制當中,無論是哪個操作系統(tǒng)下,都不要
長時間的鎖住資源,如果一直鎖定資源,就會一致阻止其他線程的執(zhí)行,
使整個程序,處于完全停止的狀態(tài)。
不要在critical section中調(diào)用Sleep或任何Wait等待之類的api函數(shù).
、、、 臨界區(qū)很容器造成資源死鎖.
相關(guān)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ū),也就意味著我進行加鎖,在他之后已經(jīng)加鎖了
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內(nèi)核模式下的同步對象是可以進行,安全的跨進程操作,但是他相對與用戶模式,速度比較慢, 因此正常情況下,使用
臨界區(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); //關(guān)閉線程句柄 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ū)的指針內(nèi)存 DeleteCriticalSection(&g_cs); PostQuitMessage(0); break;
然后觀察線程的回調(diào)函數(shù)
DWORD WINAPI ThrCalcProc1(LPVOID lp) { //獲得結(jié)構(gòu)體指針 PPARAMS param2 = static_cast(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) { //檢查文本是否超出窗口顯示范圍,如果是就刷新窗口,并重新設(shè)置iLine值 //g_iLine2 = CheckTextRange(param2->hwnd, param2->cyChar, param2->cyChar,g_iLine2); //隨機產(chǎn)生兩個數(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; }
代碼下載地址:http://down.51cto.com/data/2329647