1. // 004_完成端口.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    2. //
    3. #include <windows.h>
    4. #include <stdio.h>
    5. struct MyOverlapped : public OVERLAPPED {
    6. MyOverlapped()
    7. {
    8. // 将OVERLAPPED部分填充为0
    9. memset(this, 0, sizeof(OVERLAPPED));
    10. pBuff = NULL;
    11. }
    12. char *pBuff;
    13. ~MyOverlapped() {
    14. if (pBuff) {
    15. delete pBuff;
    16. }
    17. }
    18. };
    19. DWORD WINAPI threadProc(LPVOID pArg)
    20. {
    21. HANDLE hIoComp = (HANDLE)pArg;
    22. DWORD dwBytes = 0;
    23. ULONG_PTR completionKey = 0;
    24. MyOverlapped* pOv=NULL;
    25. BOOL ret = 0;
    26. while ( 1 )
    27. {
    28. ret = GetQueuedCompletionStatus(
    29. hIoComp,
    30. &dwBytes,/*实际完成的字节数*/
    31. &completionKey,/*和文件设备关联在一起的完成键*/
    32. (OVERLAPPED**)&pOv,/*通过ReadFile投递IO任务时传递重叠结构*/
    33. -1/*超时时间*/);
    34. if (ret == FALSE) {
    35. continue;
    36. }
    37. printf("读取偏移:[%d]的IO任务完成, 实际读取到的字节数:%d"
    38. "读取到的内容是:%s",
    39. pOv->Offset,
    40. pOv->InternalHigh,
    41. pOv->pBuff);
    42. delete pOv;
    43. }
    44. return 0;
    45. }
    46. int main()
    47. {
    48. // 1. 创建异步IO方式的文件对象
    49. HANDLE hFile = INVALID_HANDLE_VALUE;
    50. hFile = CreateFile(
    51. L"004_完成端口.cpp",
    52. GENERIC_READ,/*读写方式:只读*/
    53. FILE_SHARE_READ,/*共享方式: 共享读*/
    54. NULL,/*安全描述符*/
    55. OPEN_EXISTING,/*创建标志:存在时才打开*/
    56. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,/*文件属性和标志:正常属性|重叠IO标志 */
    57. NULL);
    58. // 2. 创建一个完成端口对象
    59. SYSTEM_INFO si = { 0 };
    60. GetSystemInfo(&si);
    61. HANDLE hIoComp = CreateIoCompletionPort(
    62. INVALID_HANDLE_VALUE,
    63. NULL,
    64. NULL,
    65. si.dwNumberOfProcessors/*处理器个数*/);
    66. // 3. 将完成端口和文件对象进行绑定
    67. CreateIoCompletionPort(
    68. hFile,/*要和完成端口进行绑定的文件句柄*/
    69. hIoComp,/*绑定到哪个完成端口上*/
    70. 0,/*完成键, 和文件句柄关联的值*/
    71. 0);
    72. // 4. 创建指定个数线程, 在线程监视完成端口 完成列表的状态
    73. for (int i = 0; i < si.dwNumberOfProcessors; ++i) {
    74. CreateThread(0, 0,&threadProc, hIoComp, 0, 0);
    75. }
    76. DWORD read = 0;
    77. // 5. 发起异步IO任务.
    78. for (int i = 0; i < 100; ++i) {
    79. MyOverlapped* pOv = new MyOverlapped;
    80. pOv->pBuff = new char[50];
    81. memset(pOv->pBuff, 0, 50);
    82. pOv->Offset = i * 40;
    83. ReadFile(hFile, pOv->pBuff, 40, &read, pOv);
    84. }
    85. while ( 1 )
    86. {
    87. Sleep(1000);
    88. }
    89. }