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

Win32線程編程核心詳解:創建/同步/優先級/終止/內核對象全生命周期

     編輯:關於C語言

Win32線程編程核心詳解:創建/同步/優先級/終止/內核對象全生命周期

Win32 API 提供了豐富的線程管理機制。本文基於《Windows程序設計》學習筆記,系統梳理線程核心概念、關鍵API(CreateThread/WaitForSingleObject/WaitForMultipleObjects/SetThreadPriority/ExitThread/TerminateThread)、內核對象結構、上下文切換、優先級體系、終止方式及最佳實踐,附帶完整可編譯示例代碼。

核心概念速覽

概念說明
線程進程內代碼執行路徑,擁有獨立棧、寄存器上下文、線程局部存儲(TLS)
_stdcallWin32回調函數調用約定:參數右至左入棧,被調用者清棧(callee cleanup)
線程內核對象內核維護的數據結構,包含:上下文、使用計數、暫停計數、退出碼、信號狀態等
受信/非受信線程運行中=非受信;線程結束=受信。Wait函數等待對象變為受信
使用計數創建時=2(內核引用+句柄引用),CloseHandle遞減,歸零時對象銷毀
暫停計數CREATE_SUSPENDED創建時=1,ResumeThread遞減,歸零時獲得CPU調度

關鍵API詳細解析

1. 創建線程:CreateThread

HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,  // 安全屬性,NULL=默認
    SIZE_T dwStackSize,                        // 棧大小,0=默認1MB
    LPTHREAD_START_ROUTINE lpStartAddress,     // 線程入口函數
    LPVOID lpParameter,                        // 傳給入口函數的參數
    DWORD dwCreationFlags,                     // 0=立即運行, CREATE_SUSPENDED=掛起
    LPDWORD lpThreadId                         // 輸出:線程ID
);

2. 等待單對象:WaitForSingleObject

DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
// dwMilliseconds: INFINITE=無限等待, 0=嘗試, >0=超時毫秒數
// 返回: WAIT_OBJECT_0(受信), WAIT_TIMEOUT(超時), WAIT_FAILED(失敗)

3. 等待多對象:WaitForMultipleObjects

DWORD WaitForMultipleObjects(
    DWORD nCount,           // 對象數量(最大 MAXIMUM_WAIT_OBJECTS=64)
    CONST HANDLE* lpHandles, // 句柄數組
    BOOL bWaitAll,          // TRUE=全部受信, FALSE=任一受信
    DWORD dwMilliseconds    // 超時
);
// 返回: WAIT_OBJECT_0 + index (bWaitAll=FALSE時), WAIT_OBJECT_0 (bWaitAll=TRUE時)

4. 線程優先級:SetThreadPriority

BOOL SetThreadPriority(HANDLE hThread, int nPriority);
// 相對優先級常量(從高到低):
// THREAD_PRIORITY_TIME_CRITICAL (15)
// THREAD_PRIORITY_HIGHEST (2)
// THREAD_PRIORITY_ABOVE_NORMAL (1)
// THREAD_PRIORITY_NORMAL (0)  ← 默認
// THREAD_PRIORITY_BELOW_NORMAL (-1)
// THREAD_PRIORITY_LOWEST (-2)
// THREAD_PRIORITY_IDLE (-15)

// 進程優先級類別(影響線程基礎優先級):
// IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS,
// ABOVE_NORMAL_PRIORITY_CLASS, HIGH_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS

5. 線程終止四種方式(推薦度遞減)

  1. 自然返回:線程函數執行完 return — 最推薦,正確調用析構函數、釋放棧、設置退出碼、遞減使用計數
  2. ExitThread:當前線程主動退出 — 不調用C++析構函數,資源洩漏風險
  3. TerminateThread:強制終止其他線程 — 極度危險,可能死鎖、資源洩漏、棧不釋放,嚴禁使用
  4. ExitProcess:終止整個進程 — 相當於對所有線程調用 TerminateThread,嚴禁使用

完整示例代碼

示例1:基礎線程創建與等待

#include <stdio.h>
#include <windows.h>

DWORD WINAPI ThreadProc(LPVOID lpParam) {
    for (int i = 0; i < 20; i++) {
        printf("Thread running, count = %d\n", i);
    }
    return 0;
}

int main() {
    HANDLE hThread;
    DWORD dwThreadId;

    hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &dwThreadId);
    printf("Thread created, ID = %d\n", dwThreadId);

    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    return 0;
}

示例2:優先級演示(Idle vs Normal)

DWORD WINAPI ThreadIdle(LPVOID lpParam) {
    for (int i = 0; i < 10; i++) printf("Idle Thread running\n");
    return 0;
}

DWORD WINAPI ThreadNormal(LPVOID lpParam) {
    for (int i = 0; i < 10; i++) printf("Normal Thread running\n");
    return 0;
}

int main() {
    HANDLE h[2];
    DWORD dwThreadId;

    // Idle優先級線程:創建掛起 -> 設置優先級 -> 恢復
    h[0] = CreateThread(NULL, 0, ThreadIdle, NULL, CREATE_SUSPENDED, &dwThreadId);
    SetThreadPriority(h[0], THREAD_PRIORITY_IDLE);
    ResumeThread(h[0]);

    // Normal優先級線程:直接運行
    h[1] = CreateThread(NULL, 0, ThreadNormal, NULL, 0, &dwThreadId);

    // 等待兩者都結束
    WaitForMultipleObjects(2, h, TRUE, INFINITE);
    CloseHandle(h[0]); CloseHandle(h[1]);
    return 0;
}

最佳實踐總結

  1. 使用 _beginthreadex 替代 CreateThread:C/C++運行時正確初始化線程局部存儲、避免內存洩漏(需鏈接MT運行庫)
  2. 創建即掛起模式:CREATE_SUSPENDED → 設置優先級/親和性/棧大小 → ResumeThread,避免競態
  3. 線程同步用內核對象:事件、互斥量、信號量、關鍵區 — 避免忙等待
  4. 優雅退出機制:全局標志位/事件對象通知線程退出,線程函數自然 return
  5. 句柄管理:CreateThread 返回句柄必須 CloseHandle,否則洩漏內核對象引用
  6. 避免 TerminateThread:任何情況下不得使用,設計時預留退出路徑

總結

Win32線程編程的核心在於理解內核對象生命周期(使用計數、信號狀態、暫停計數)、優先級體系(進程類別+線程相對優先級)與同步原語的正確組合。牢記「自然返回是唯一正確的終止方式」,配合 _beginthreadex、CREATE_SUSPENDED、事件驅動退出模式,即可編寫健壯、高性能的多線程Windows應用。

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