亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

VC++線程同步(二) Mutex互斥量的例子

發布時間:2020-06-25 23:12:08 來源:網絡 閱讀:1318 作者:超級極客 欄目:編程語言

                 同步對象使用實例 


Win32窗口的建立:

    我們將要學習的使用,分別是:互斥量,臨界區,事件,信號量.所以我們需要一個窗口,呈現四種四種同步對象狀態.


需要學到的目的有4點:

1 掌握內核同步對象觸發規則(是內核同步對象)

2 弄懂同步等待成功引起的副作用

3 了解各個同步對象的運行流程

4 明白內核同步對象和用戶同步對象的異同點

一般掌握上面4種核心知識,就能放心大膽的使用多線程了。




首先創建一個Win32項目,不要選空項目;

我們需要四個小窗口,先找到注冊主窗口的代碼。

ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style= CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc= WndProc;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInstance;
wcex.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName= MAKEINTRESOURCE(IDC_WIN32PROJECT1);
wcex.lpszClassName= szWindowClass;
wcex.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}

VC++線程同步(二) Mutex互斥量的例子


不重要的部分(就是Win32窗口流程):先創建的是注冊一個主窗口的Windows的類結構,并且賦值給他一個窗口的Proc函數,然后調用InitInstance創建一個主窗口.



子窗口創建: WM_CREATE 就是創建的

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

直接貼出完整代碼:


其中WndProc1是子窗口的消息處理函數

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
static int clientCX = 0;
static int clientCY = 0;
static TCHAR *szChildClass[] = { _T("Child1"), _T("Child2"), _T("Child3"), _T("Child4") };//子窗口名字
static WNDPROC childWndProc[] = { WndProc1, WndProc2, WndProc3, WndProc4 };//子窗口的消息處理函數
static HWND hwndChild[4]; //子窗口句柄
switch (message)
{
case WM_CREATE:
{
//對四個UI窗口類進行統一初始化
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style= CS_HREDRAW | CS_VREDRAW;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInst;
wcex.hIcon= NULL;
wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName= NULL;
wcex.hIconSm= NULL;
for (int i = 0; i < CHILD_WND_COUNT;++i) 
{
//對不同的部分進行分別初始化
wcex.lpfnWndProc = childWndProc[i];
wcex.lpszClassName = szChildClass[i];
//注冊窗口類
RegisterClassEx(&wcex);
//創建窗口  并且記錄窗口句柄
hwndChild[i] = CreateWindow(
szChildClass[i],
_T(""),
WS_CHILD | WS_BORDER | WS_VISIBLE,
0, 0, 0, 0,
hWnd,
(HMENU)i,
hInst,
NULL);
}
}
break;
case WM_SIZE:
{
clientCX = LOWORD(lParam);//客戶區的寬度
clientCY = HIWORD(lParam);//客戶區的高度
for (int i = 0; i < CHILD_WND_COUNT; ++i)
{
// 移動窗口的位置和其大小
MoveWindow(
hwndChild[i],
(i % 2)*clientCX / 2, (i > 1)*clientCY / 2,
clientCX / 2, clientCY / 2,
TRUE
);
}
}
break;
case WM_COMMAND:
wmId    = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜單選擇: 
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO:  在此添加任意繪圖代碼...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WndProc1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static THRPARAMS thrParams;
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
{
//系統中基于對話框字體的高度
int cyChar = HIWORD(GetDialogBaseUnits());
//填充THRPARAMS結構體
thrParams.hwnd = hWnd;
thrParams.cyChar = cyChar;
//創建一個當前線程沒有擁有所有權的 互斥對象
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜單選擇: 
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO:  在此添加任意繪圖代碼...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}




              1 演示創建一個Mutex互斥量


火車售票系統。

創建兩個線程,演示如何進行資源的保護。兩個線程競爭某個資源。



case WM_CREATE:
{
//系統中基于對話框字體的高度
int cyChar = HIWORD(GetDialogBaseUnits());
//填充THRPARAMS結構體
thrParams.hwnd = hWnd;
thrParams.cyChar = cyChar;
//創建一個當前線程沒有擁有所有權的 互斥對象 
//FALSE技術遞歸計數器為0 線程id為0 所以是觸發狀態
g_hMutex = CreateMutex(NULL, FALSE, NULL);
//創建兩個線程來賣火車票
HANDLE handleTicket1 = CreateThread(NULL, 0, ThrTicketProc1, &thrParams, 0, NULL);
HANDLE handleTicket2 = CreateThread(NULL, 0, ThrTicketProc2, &thrParams, 0, NULL);
/*
原因為:創建線程后返回了線程句柄,新創建的線程內核對象的使用計數是2,一個是線程本身,一個是
創建線程的線程,創建新的線程CloseHandle后,新的線程內核對象使用計數為1,當這個新線程結束運行后
內核對象的使用技術還要減1,這時內核對象的使用計數是0,則系統會自動刪除新線程的內核對象,這是
正常的處理流程.
如果不調用CloseHandle()則新線程運行結束后,由于使用計數為1,所以不會刪除線程的內核對象,這樣
就會造成內存泄漏,當然在整個程序運行結束后,操作系統會回首這些內存,因此可以知道如果不調用
CloseHandle的話,該程序在運行階段,會造成內存泄漏。
*/
//關閉線程句柄
CloseHandle(handleTicket1);
CloseHandle(handleTicket2);
}


//釋放互斥量對象的句柄 在窗口關閉前
case WM_DESTROY:
// 關閉 互斥量句柄內存 刪除
CloseHandle(g_hMutex);
PostQuitMessage(0);
break;




來看這個線程函數怎么用:

兩個線程都對火車票的票數,也就是全局變量,來進行操作。

我們要避免就是同時兩個線程拿到這個變量,同時進行讀寫操作。

導致資源,脫離控制,要做到一個線程拿到這個資源立即鎖定,只有他

完成,其他線程才能進行訪問。

只需要修改其中的線程名輸出就可以觀測了.

DWORD WINAPI ThrTicketProc1(LPVOID lp)
{
//將輸入的參數 轉換成結構體
PPARAMS param = static_cast<PPARAMS>(lp);
TCHAR szBuf[20] = { 0 };
HDC hdc;
//進入死循環
while (true)
{
//等待函數 無限等待,知道g_hMutex這個互斥量對象觸發。
//不需要判斷返回值因為參數用的INFINITE,肯定有一個線程拿到這個所有權
WaitForSingleObject(g_hMutex, INFINITE);
//如果票數大于0  g_trainTickets是一個全局變量
if (g_trainTickets > 0)
{
//在這里休眠 一下, 暫時放棄剩余的時間片
Sleep(800);
//銷售火車票
// 打印表示哪個線程銷售的火車票
wsprintf(szBuf, _T("線程1剩余火車票:%d"), g_trainTickets--);
// 獲得繪圖句柄
hdc = GetDC(param->hwnd);
//將字體繪制到子窗口中
TextOut(hdc, 0, g_iLine*param->cyChar, 
szBuf, lstrlen(szBuf));
ReleaseDC(param->hwnd,hdc);
//清空字符串
memset(szBuf, 0, sizeof(TCHAR) * 20);
//全局變量行數 
g_iLine++;
//整個子窗口 重新繪制
InvalidateRect(param->hwnd,NULL,FALSE);
//解鎖釋放 這個互斥量對象 使他觸發
ReleaseMutex(g_hMutex);
}
else
{
//解鎖釋放 這個互斥量對象 使他觸發
ReleaseMutex(g_hMutex);
break;
}
}
return 0;
}


我門發現井然有序,如果我們不釋放Release會造成死鎖,這樣其他

等待的線程,或永遠在等待,不會被觸發。
VC++線程同步(二) Mutex互斥量的例子


如果我們使用Wait等待函數,那WaitForSingleObject注釋掉。

兩個線程同時訪問一個資源,進行讀寫,導致資源脫離控制。


VC++線程同步(二) Mutex互斥量的例子




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

简阳市| 合作市| 星座| 阳山县| 定边县| 黑龙江省| 清水河县| 江达县| 逊克县| 梓潼县| 文安县| 台前县| 惠州市| 长寿区| 阿拉尔市| 铅山县| 上林县| 沐川县| 靖边县| 同德县| 哈巴河县| 论坛| 临夏县| 元谋县| 江油市| 潜江市| 阳谷县| 武强县| 深泽县| 武胜县| 海阳市| 乌拉特前旗| 南溪县| 肇东市| 林周县| 漯河市| 若羌县| 德兴市| 遵义市| 杭锦旗| 舞钢市|