用 QueueUserAPC() 函式來強制執行緒退出等待狀態
阿新 • • 發佈:2019-01-22
當系統建立一個執行緒的時候,會同時建立一個與執行緒相關的佇列。這個佇列被成為非同步過程呼叫(APC)佇列。同時我們也知道,windows提供了6個函式可以等待並將執行緒設定為可提醒狀態---------
SleepEx(),
WaitForSingleObjectEx(),
WaitForMultipleObjectsEx(),
SignalObjectAndWait(),
GetQueuedCompletionStatusEx(),
MsgWaitForMultipleObjectsEx()
當我們呼叫這6個函式之一併將執行緒設定為可提醒狀態的時候,系統會首先檢查執行緒的APC佇列。如果佇列中至少有一項,那麼系統不會讓執行緒進入睡眠狀態。
需要牢記:當帶呼叫這些函式的時候,只要執行緒的APC佇列中至少有一項,執行緒就不會進入睡眠狀態。
這個6個函式的返回值也是很重要的:如果是WAIT_IO_COMPLETION,那麼我們就知道執行緒得以執行的原因是執行緒至少處理了APC中的一項。
windows提供了一個函式,允許我們手動的新增一項到指定執行緒的APC佇列中:
DWORD WINAPI QueueUserAPC(
__in PAPCFUNC ,
__in HANDLE ,
__in ULONG_PTR
)
用這個函式,我們可以強制讓執行緒退出等待狀態,看程式碼:
// QueueUserAPC退出執行緒.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> #include <windows.h> #include <process.h> using namespace std; VOID WINAPI APCFunc(ULONG_PTR dwParam) { //do nothing cout<<"APC函式"<<endl; } DWORD WINAPI ThreadFun(PVOID pvParam) { HANDLE hEvent = (HANDLE)pvParam; DWORD dw = WaitForSingleObjectEx(hEvent,INFINITE,TRUE); if(dw == WAIT_OBJECT_0) { //如果事件被觸發.... cout<<"事件觸發"<<endl; } if(dw == WAIT_IO_COMPLETION) { //如果執行緒至少處理了APC佇列中的一項 cout<<"處理了APC 專案"<<endl; return 0; } cout<<"等待成功"<<endl; return 0; } int _tmain(int argc, _TCHAR* argv[]) { HANDLE hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); HANDLE hThread = (HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall *)(void *))ThreadFun,(PVOID)hEvent,0,NULL); //執行一些其他程式碼 //此時使用者想要終止子執行緒 Sleep(1000); //這裡等待一秒很重要,因為最起碼要留出時間先讓子執行緒進入等待(可提醒)狀態哦。 QueueUserAPC(APCFunc,hThread,NULL); WaitForSingleObject(hThread,INFINITE); system("pause"); return 0; }