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

溫馨提示×

溫馨提示×

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

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

VC++線程同步(四) 事件使用例子

發布時間:2020-06-21 21:58:36 來源:網絡 閱讀:724 作者:超級極客 欄目:編程語言

                        事件(Event)同步對象


(內核級別)事件內核對象包含:

1 一個使用計數器

2 一個表示事件是否是自動重置還是手動重置的布爾值

3 一個表示事件有沒有被觸發的布爾值

4 當觸發為true時,等待該事件的線程變為可調度狀態

5 事件的觸發表示一個操作已經完成


作用: 通知其他線程,我已經完成讀寫操作了,輪到你們來做了。


他分為兩種類型:

1是手動重置事件,也就是要進行手動的觸發和非觸發狀態的切換.

2是自動重置事件,這種情況下只需要設置觸發事件,不用管什么時候切換觸發狀態。

盡量使用手動重置方式, 因為這種方式可控性強,不易出錯.自動重置事件會引起成功等待的一些副作用.




相關的api:


1 CreateEvent函數

HANDLE CreateEvent(

LPSECURITY_ATTRIBUTES lpEventAttributes,//安全屬性

BOOL bManualReset,  //復位方式

BOOL bInitialState,//初始狀態

LPCTSTR lpName     //對象名稱); 


返回一個Handle,事件同步對象的句柄。


參數1 lpEventAttributes    權限,一般NULL就是默認權限

參數2 bManualReset        TRUE代表手動重置,FALSE自動重置

參數3 bInitialState       TRUE代表可觸發, FALSE非觸發(阻塞)

參數3 lpName              一個對象的名稱,跨進程尋址,一般NULL




2 SetEvent函數,設置事件對象為有信號狀態

BOOL SetEvent( HANDLE hEvent);

hEvent 設置事件對象的句柄  就是CreateEvent返回的句柄.

當調用這個函數后,這個事件就是觸發的狀態。




3 ResetEvent 函數,設置事件對象為無信號,非觸發

BOOL ResetEvent(HANDLE hEvent);

hEvent 設置事件對象的句柄  就是CreateEvent返回的句柄.

當調用這個函數后,這個事件就是非觸發的狀態。




                    使用例子


還是用之前的代碼,就是一個小球碰到邊界會反彈的程序.

我們需要三個線程,三個全局的事件對象句柄.

WndProc3中代碼如下:

case WM_CREATE:
{
//系統中基于對話框字體的高度
int cyChar = HIWORD(GetDialogBaseUnits());
thrParams3.hwnd = hWnd;
thrParams3.cyChar = cyChar;
//創建事件對象
g_hEvent1 = CreateEvent(NULL, TRUE,TRUE,NULL);  //手動復位  事件 有信號
g_hEvent2 = CreateEvent(NULL, TRUE, FALSE, NULL);//手動復位 事件 無信號
g_hEvent3 = CreateEvent(NULL, TRUE, FALSE, NULL);//手動復位 事件 無信號
// 創建三個線程
HANDLE handleBall1 = CreateThread(NULL, 0, ThrBallProc1, &thrParams3, 0, NULL);
HANDLE handleBall2 = CreateThread(NULL, 0, ThrBallProc2, &thrParams3, 0, NULL);
HANDLE handleBall3 = CreateThread(NULL, 0, ThrBallProc3, &thrParams3, 0, NULL);
//關閉線程句柄
CloseHandle(handleBall1);
CloseHandle(handleBall2);
CloseHandle(handleBall3);
}


上面三個事件都是要手動復位的。

來看線程函數

前面依然使用WaitForSingleObject來進行等待,但是用的是事件的對象, 然后最好要手動的設置事件的信號。

DWORD WINAPI ThrBallProc1(LPVOID lp)
{
PPARAMS param3 = static_cast<PPARAMS>(lp);
//休眠1秒
Sleep(1000);
//等待事件 使用INFINITE所以是無限等待 只有觸發才返回
WaitForSingleObject(g_hEvent1, INFINITE);
//獲取dc
HDC hdc = GetDC(param3->hwnd);
//生成隨機數種子
srand(GetTickCount());
//創建筆和畫刷
HPEN white_pen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));  //綠色的小球
HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255));
//小球的開始位置
int ball_x = param3->cxClient / 2;
int ball_y = param3->cyClient / 2;
//速度
int xv = -4 + rand() % 8;
int yv = -4 + rand() % 8;
DWORD dwCurTime = GetTickCount();
while (1)
{
//首先選擇白色筆和白色畫刷 設置上下文中去
SelectObject(hdc, white_pen);
SelectObject(hdc, white_brush);
// 繪制圓形小球
Ellipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);
//移動小球
ball_x += xv;
ball_y += yv;
//如果x軸  碰到邊界 那就往反方向走
if (ball_x <0 || ball_x > param3->cxClient - 32)
{
xv = -xv;
ball_x += xv;
}
else  // 或者是Y軸
{
if (ball_y <17 || ball_y > param3->cyClient - 32)
{
yv = -yv;
ball_y += yv;
}
}
SelectObject(hdc, white_pen);
SelectObject(hdc, green_brush);
//畫小球
Ellipse(hdc, ball_x, ball_y, ball_x + 32, ball_y + 32);
DWORD dwTime = GetTickCount() - dwCurTime;  //當前時間 和第一次運行的時間差 
Sleep(10);
//判斷現在的時間 減去初始化時間(循環外的那個時間) 是不是大于10秒鐘
if ((GetTickCount() - dwCurTime) > 1000 * 10)
{
//完成了當前線程操作
break;
}
}
//線程的工作完成
//刪除GDI對象
DeleteObject(white_brush);
DeleteObject(green_brush);
DeleteObject(white_pen);
ReleaseDC(param3->hwnd,hdc );
//設置窗口無效,并更新窗口
InvalidateRect(param3->hwnd,NULL,TRUE);
UpdateWindow(param3->hwnd);
// 手動設置事件信號
//讓1號 事件對象  無信號  讓2號事件  有信號
ResetEvent(g_hEvent1);
SetEvent(g_hEvent2);
return 0;
}



我們看到,三個線程都有一個繪制小球,但是他門沒有同步出現,
而是第一個小球操作完10秒(或者是某個操作完成),他必須是有

一個對象,手動的設置觸發,那這個等待函數對應的就會返回。


VC++線程同步(四)  事件使用例子

VC++線程同步(四)  事件使用例子




如果使用自動重置事件呢?


//創建事件對象
g_hEvent1 = CreateEvent(NULL, FALSE,TRUE,NULL);  //改成自動復位
g_hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);
g_hEvent3 = CreateEvent(NULL, FALSE, FALSE, NULL);


然后在這個等待函數當作

WaitForSingleObject,當等待到了一個Event事件,他是觸發狀態,

他會判斷他是不是自動重置事件的,如果是自動重置事件的話,

他會立即調用ResetEvent將這個事件設置成,非觸發狀態.

這種情況下, 最后可以不掉用這個函數。

因為他在等待函數中,以及調用了這個函數.

然后將這個ResetEvent注釋掉,
這樣就變成自動復位的了。


VC++線程同步(四)  事件使用例子










向AI問一下細節

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

AI

清流县| 宿松县| 浪卡子县| 保定市| 彭阳县| 金昌市| 高阳县| 六枝特区| 舞钢市| 房产| 上蔡县| 洮南市| 新竹市| 英德市| 那曲县| 长治县| 永春县| 法库县| 南平市| 沾化县| 唐河县| 漳州市| 依安县| 敦化市| 丰台区| 武安市| 台南市| 平果县| 汪清县| 射洪县| 安丘市| 清流县| 滦平县| 开封市| 墨竹工卡县| 浏阳市| 剑川县| 永嘉县| 青川县| 吴旗县| 澜沧|