系統創建新執行緒時,會同時創建與這個執行緒相關聯的佇列,即異步程序呼叫(APC)的佇列,
一些異步操作可以通過加入APC來實作,比如我現在學習的IO請求/完成,
BOOL ReadFileEx( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);IO完成時,系統向該執行緒的APC佇列中加入一項,包含lpCompleteionRoutine和lpOverlapped,當執行緒處于非執行態且是可提醒的狀態時,系統會取出APC中的項,并讓執行緒執行其中的回呼函式,這個動作會重復到佇列空,我猜想可能還會被執行緒正常喚醒打斷,
非執行態是執行緒呼叫了等待、休眠函式,像
DWORD SleepEx(DWORD dwMilliseconds, bool bAlertable );
DWORD WaitForSigleObjectEx(HANDLE hObject,DWORD dwMilliseconds,bool bAlertable);
bAlertable=true; 是可提醒狀態!
另一段APC call的代碼,是一個waitableTimer的例子,
#include <iostream>#include<process.h>#include<Windows.h>#include<tchar.h>#include<string.h>void APIENTRY TimerAPCRoutine(PVOID pvArgToCompleteRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue);void SomeFunc(){ HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL); LARGE_INTEGER li = { 0 }; SetWaitableTimer(hTimer, &li, 5000, TimerAPCRoutine, NULL, false); SleepEx(INFINITE, true); CloseHandle(hTimer);}void APIENTRY TimerAPCRoutine(PVOID pvArgToCompleteRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue){ FILETIME ftUTC, ftLocal; SYSTEMTIME st; TCHAR szBuf[256]; ftUTC.dwHighDateTime = dwTimerHighValue; ftUTC.dwLowDateTime = dwTimerLowValue; FileTimeToLocalFileTime(&ftUTC, &ftLocal); FileTimeToSystemTime(&ftLocal, &st); GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szBuf, _countof(szBuf)); _tcscat_s(szBuf, _countof(szBuf), " "); GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, _tcschr(szBuf, TEXT('\0')), (int)(_countof(szBuf) - _tcslen(szBuf))); MessageBox(NULL, szBuf, TEXT("Timer went off at ..."), MB_OK);}int wmain(int argc, wchar_t* argv[]){ SomeFunc(); char c; std::cin >> c; return 0;}
執行緒跑到APC回呼函式時,

總結:
APC是由系統管理的與執行緒相關的佇列,可用來執行異步操作,
APC的回呼函式是在原執行緒休眠時在原執行緒上呼叫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/27234.html
標籤:Windows
