多執行緒讓單一進程內並發執行多條指令流,提升回應性與吞吐量。本文說明執行緒分類、CreateThread 建立機制、三種執行緒間通訊模式(全域變數、視窗訊息、事件對象),並提供 MASM 範例展示 UI 執行緒與工作執行緒協作模式。
建議架構:主執行緒專司 UI,耗時運算委派工作執行緒,避免介面凍結。
CreateThread proto lpThreadAttributes:DWORD,
dwStackSize:DWORD,
lpStartAddress:DWORD,
lpParameter:DWORD,
dwCreationFlags:DWORD,
lpThreadId:DWORD
lpStartAddress:執行緒函式入口,簽名 DWORD WINAPI ThreadProc(LPVOID)dwCreationFlags:0=立即執行,CREATE_SUSPENDED=暫停建立,稍後 ResumeThread 啟動WaitForSingleObject 等待結束,應立即 CloseHandle。| 模式 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| 全域變數 | 同進程內所有執行緒 | 簡單直接,無系統呼叫開銷 | 需自行處理同步(Critical Section, Mutex 等),除錯困難 |
| 視窗訊息 | UI 執行緒間、或工作執行緒→UI 執行緒 | 系統內建序列化,無競爭條件 | 工作執行緒無訊息佇列,無法接收訊息 |
| 事件對象 | 任意執行緒同步、喚醒 | 核心級同步,高效低佔用 | 僅適合訊號通知,不適合傳遞複雜資料 |
UI 執行緒 --自訂訊息(PostMessage)--> 工作執行緒
工作執行緒 --全域旗標/事件--> UI 執行緒
主視窗選單「Create Thread」啟動工作執行緒執行 6 億次加法,完成後 PostMessage(hwnd, WM_FINISH, 0, 0) 通知 UI 執行緒彈出訊息框。WM_FINISH = WM_USER + 0x100 避免與系統訊息衝突。
ThreadProc PROC USES ecx Param:DWORD
mov ecx, 600000000
Loop1:
add eax, eax
dec ecx
jz Get_out
jmp Loop1
Get_out:
invoke PostMessage, hwnd, WM_FINISH, NULL, NULL
ret
ThreadProc ENDP
.ELSEIF uMsg==WM_FINISH
invoke MessageBox, NULL, ADDR SuccessString, ADDR AppName, MB_OK
擴充上例:選單新增「Kill Thread」,設全域 CommandFlag=TRUE;工作執行緒迴圈中檢測旗標,為真則跳出結束。
; 資料段
CommandFlag BOOL FALSE
; 選單處理
.if ax==IDM_KILL_THREAD
mov CommandFlag, TRUE
...
; 工作執行緒迴圈
.WHILE ecx!=0
.if CommandFlag==TRUE
jmp Get_out
.endif
add eax, eax
dec ecx
.ENDW
參考前文(事件對象教程),使用 CreateEvent + WaitForSingleObject 實現「啟動/暫停/繼續」精確控制,避免輪詢旗標浪費 CPU。
CreateThread 返回控制碼若不等待執行緒結束,立即 CloseHandle。__try/__except 防止未處理例外導致進程崩潰。Win32 多執行緒核心在於 CreateThread 建立、訊息機制跨執行緒通訊(UI 端)、事件/旗標同步(工作端)。掌握「主執行緒做 UI、工作執行緒做運算」分工原則,配合 PostMessage 非阻塞通知與事件對象精確同步,即能編寫高回應性、穩定的多執行緒應用程式。