经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Windows » 查看文章
APC (Asynchronous Procedure Call)
来源:cnblogs  作者:武方绿  时间:2019/10/14 9:52:31  对本文有异议

系统创建新线程时,会同时创建与这个线程相关联的队列,即异步过程调用(APC)的队列。

一些异步操作可以通过加入APC来实现,比如我现在学习的IO请求/完成。

  1. BOOL ReadFileEx(
  2. HANDLE hFile,
  3. LPVOID lpBuffer,
  4. DWORD nNumberOfBytesToRead,
  5. LPOVERLAPPED lpOverlapped,
  6. LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
  7. );

IO完成时,系统向该线程的APC队列中加入一项,包含lpCompleteionRoutine和lpOverlapped。当线程处于非执行态且是可提醒的状态时,系统会取出APC中的项,并让线程执行其中的回调函数。这个动作会重复到队列空,我猜想可能还会被线程正常唤醒打断。

非执行态是线程调用了等待、休眠函数,像

  1. DWORD SleepEx(DWORD dwMilliseconds, bool bAlertable );
    DWORD WaitForSigleObjectEx(HANDLE hObject,DWORD dwMilliseconds,bool bAlertable);

bAlertable=true; 是可提醒状态!

另一段APC call的代码,是一个waitableTimer的例子。

  1. #include <iostream>
  2. #include<process.h>
  3. #include<Windows.h>
  4. #include<tchar.h>
  5. #include<string.h>
  6. void APIENTRY TimerAPCRoutine(PVOID pvArgToCompleteRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue);
  7. void SomeFunc()
  8. {
  9. HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
  10. LARGE_INTEGER li = { 0 };
  11. SetWaitableTimer(hTimer, &li, 5000, TimerAPCRoutine, NULL, false);
  12. SleepEx(INFINITE, true);
  13. CloseHandle(hTimer);
  14. }
  15. void APIENTRY TimerAPCRoutine(PVOID pvArgToCompleteRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue)
  16. {
  17. FILETIME ftUTC, ftLocal;
  18. SYSTEMTIME st;
  19. TCHAR szBuf[256];
  20. ftUTC.dwHighDateTime = dwTimerHighValue;
  21. ftUTC.dwLowDateTime = dwTimerLowValue;
  22. FileTimeToLocalFileTime(&ftUTC, &ftLocal);
  23. FileTimeToSystemTime(&ftLocal, &st);
  24. GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szBuf, _countof(szBuf));
  25. _tcscat_s(szBuf, _countof(szBuf), " ");
  26. GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, _tcschr(szBuf, TEXT('\0')), (int)(_countof(szBuf) - _tcslen(szBuf)));
  27. MessageBox(NULL, szBuf, TEXT("Timer went off at ..."), MB_OK);
  28. }
  29. int wmain(int argc, wchar_t* argv[])
  30. {
  31. SomeFunc();
  32. char c;
  33. std::cin >> c;
  34. return 0;
  35. }

 

 

线程跑到APC回调函数时,

 

 

总结:

APC是由系统管理的与线程相关的队列,可用来执行异步操作。

APC的回调函数是在原线程休眠时在原线程上调用。

 

原文链接:http://www.cnblogs.com/wyh1993/p/11666673.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号