首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Windows 95 多執行緒同步事件控制:Event 物件實作詳解

     編輯:關於C++

在 Windows 95 這個多工、多執行緒的作業系統中,每個應用程式本質上都是一個行程,而行程可建立多個並發執行緒。要對獨立執行的執行緒進行有效控制(如暫停、終止、條件觸發),必須在執行緒間建立同步機制。本文深入探討如何利用 Win32 API 提供的 Event 同步物件,實現執行緒間的事件同步控制,並延伸至跨行程的同步應用。

一、執行緒基本概念與建立

Windows 95 中的執行緒是系統排程的基本單位,以函數形式存在,共享所屬行程的全域變數、檔案控制表等資源。主執行緒類似 UNIX 的父行程,建立的子執行緒獨立運行。使用 CreateThread API 建立執行緒:

hThread = CreateThread(
    NULL,               // 安全屬性(僅 NT 相關)
    0,                  // 預設堆疊大小
    &ThreadFunc,        // 執行緒入口函數
    this,               // 傳遞參數(通常為 this 指標)
    0,                  // 建立旗標
    &hThreadId          // 接收執行緒 ID
);

執行緒函數通常轉呼叫類別成員函數執行具體任務:

DWORD _stdcall TEventWindow::ThreadFunc(void *thrdWin) {
    return static_cast(thrdWin)->LoopFunc();
}

二、Event 物件與同步控制核心

Win32 提供兩類同步物件:互斥類(Mutex,協調資料存取)與事件類(Event,發送命令/觸發事件、安排執行順序)。Event 物件擁有兩種狀態:Signaled(已觸發)與 Non-signaled(未觸發)。關鍵 API:

  • CreateEvent:建立 Event,可指定手動/自動重置、初始狀態、名稱(跨行程共享需命名)。
  • SetEvent / ResetEvent:設定/重置狀態為 Signaled/Non-signaled。
  • WaitForSingleObject / WaitForMultipleObjects:等待物件進入 Signaled 狀態,支援超時與多物件等待邏輯。

三、實作範例:視窗關閉與執行緒終止的同步

場景:使用者關閉視窗時,必須先通知背景執行緒終止,待執行緒安全退出後才真正關閉視窗,避免執行緒繼續繪圖導致畫面錯亂。

1. 建立兩個自動重置 Event(初始 Non-signaled):

hCloseEvent     = CreateEvent(0, FALSE, FALSE, 0); // 通知執行緒關閉
hNoCloseEvent   = CreateEvent(0, FALSE, FALSE, 0); // 執行緒回報「暫時無法關閉」

2. 主執行緒關閉流程:

BOOL TEventWindow::CanClose() {
    HANDLE Signals[2] = { hThread, hNoCloseEvent };
    SetEvent(hCloseEvent); // 發出關閉通知
    // 等待:執行緒結束 或 執行緒回報無法關閉
    if (WaitForMultipleObjects(2, Signals, FALSE, INFINITE) == 0)
        return TRUE;  // 執行緒已結束,可關閉
    else
        return FALSE; // 執行緒回報無法關閉,暫不關閉視窗
}

3. 背景執行緒循環處理:

DWORD TEventWindow::LoopFunc() {
    HANDLE Signals[3] = { hCloseEvent, hWatchEvent, hNoBlockEvent };
    static BOOL bWatch = FALSE;
    int dwEvent;

    while (1) {
        dwEvent = WaitForMultipleObjects(3, Signals, FALSE, INFINITE);
        switch (dwEvent) {
            case 0: // 收到關閉通知
                if (iCount > 100) return 0; // 滿足條件,結束執行緒
                else SetEvent(hNoCloseEvent); // 否則回報無法關閉
                break;
            case 1: // 收到監看通知
                bWatch = TRUE;
                break;
            case 2: // 無封鎖事件(hNoBlockEvent 永遠 Signaled)
                ++iCount;
                if (bWatch && iCount > 200) SetEvent(hNtyEvent); // 觸發主執行緒繼續
                break;
        }
    }
}

關鍵設計:hNoBlockEvent 為手動重置且初始 Signaled,確保無使用者控制事件時執行緒仍能持續運行。WaitForMultipleObjects 依陣列順序檢查,優先響應使用者控制事件。

四、跨行程同步:命名 Event 共享

Event 物件在系統範圍內有效。另一行程可透過 OpenEvent 取得已命名 Event 的句柄,進而呼叫 SetEvent、ResetEvent、WaitForMultipleObjects 等函數,實現跨行程的執行緒控制。例如:

HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, "MyEvent");
ResetEvent(hEvent); // 讓對方執行緒暫停
SetEvent(hEvent);   // 讓對方執行緒繼續

這使得不同應用程式間的同步控制變得簡單直觀。

五、總結與最佳實踐

  • 多執行緒編程廣泛應用於多媒體、網路通訊、即時控制等領域。
  • 實際開發中,任務劃分為可並發執行緒、同步物件陣列順序設計(如 SignalsL)至關重要。
  • 本文機制同樣適用於 Windows NT 及支援多執行緒的 UNIX 系統(對應 POSIX 同步原語)。
  • 避免使用 TerminateThread 強制終止,應採用事件通知協同結束,確保資源正確釋放。

善用 Event 物件,能構建出健壯、可控的多執行緒應用程式架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved