C++ IO完成端口UDP套接字、实现和WSASendTo

C++ IO完成端口UDP套接字、实现和WSASendTo,c++,udp,iocp,overlapped-io,C++,Udp,Iocp,Overlapped Io,我需要开发一个在UDP套接字中使用IOCP的应用程序,但是在Microsoft文档中找到的材料作为其他示例,或者在实现形式上是模糊的或重点。我希望有使用IOCP经验的人确认正确的用法是: 调用CreateIoCompletionPort函数来创建IOCP 我将套接字与具有相同功能的IOCP关联 执行IO操作(在我的情况下为WSARecvFrom或WSASendTo) 调用GetQueuedCompletionStatus函数,该函数将阻止我的进程,直到我的IO操作完成为止(例如,这可以在线程池

我需要开发一个在UDP套接字中使用IOCP的应用程序,但是在Microsoft文档中找到的材料作为其他示例,或者在实现形式上是模糊的或重点。我希望有使用IOCP经验的人确认正确的用法是:

  • 调用CreateIoCompletionPort函数来创建IOCP
  • 我将套接字与具有相同功能的IOCP关联
  • 执行IO操作(在我的情况下为WSARecvFrom或WSASendTo)
  • 调用GetQueuedCompletionStatus函数,该函数将阻止我的进程,直到我的IO操作完成为止(例如,这可以在线程池中完成)
  • 实现对缓冲区或运算结果的读取
我没有描述套接字的实现,因为它不是重点,但这是使用IOCP的正确方法吗

第二个问题是关于发送信息的应用程序设计。我读到一些文章说,使用IOCP的应用程序不会直接调用输出操作(例如直接调用WSASendTo函数),而是使用PostQueuedCompletionStatus函数在线程中生成一个事件来运行此操作。根据我的研究,我认为在性能方面没有任何优势


假设这两种形式都应用于线程池,则使用PostQueuedCompletionStatus执行输出操作有好处?

上的Microsoft文档有许多指向后续主题的链接。有趣的是,通过使用
GetQueuedCompletionStatus()
函数在一个线程中等待消息,并在发送消息的线程中使用
PostQueuedCompletionStatus()
函数,似乎可以使用I/O完成端口在线程之间对消息进行排队,而无需任何实际I/O。有关详细信息,请参阅答案。一个问题有一个漂亮的讨论。“这是使用IOCP的正确方法吗?”-这是使用IOCP的一种方法,是的。“使用PostQueuedCompletionStatus函数在线程中生成事件以运行[an]操作”-这不是一种常见的方法,也没有实际的好处。在需要执行直接I/O操作时发出该操作没有任何问题。在Windows Vista之前,由线程启动的任何未完成的重叠I/O操作将在该线程退出时取消。为了避免出现这种问题,您可以强制在您控制其生存期的线程上执行I/O操作,方法是首先使用PostQueuedCompletionStatus()调用来传输“请求”,以向I/O线程池发出I/O请求。这种行为不再需要,因为从Windows Vista开始,当发出线程退出时,挂起的I/O请求不再被取消。这是一个不再需要的深奥的设计。上的Microsoft文档有许多指向后续主题的链接。有趣的是,通过使用
GetQueuedCompletionStatus()
函数在一个线程中等待消息,并在发送消息的线程中使用
PostQueuedCompletionStatus()
函数,似乎可以使用I/O完成端口在线程之间对消息进行排队,而无需任何实际I/O。有关详细信息,请参阅答案。一个问题有一个漂亮的讨论。“这是使用IOCP的正确方法吗?”-这是使用IOCP的一种方法,是的。“使用PostQueuedCompletionStatus函数在线程中生成事件以运行[an]操作”-这不是一种常见的方法,也没有实际的好处。在需要执行直接I/O操作时发出该操作没有任何问题。在Windows Vista之前,由线程启动的任何未完成的重叠I/O操作将在该线程退出时取消。为了避免出现这种问题,您可以强制在您控制其生存期的线程上执行I/O操作,方法是首先使用PostQueuedCompletionStatus()调用来传输“请求”,以向I/O线程池发出I/O请求。这种行为不再需要,因为从Windows Vista开始,当发出线程退出时,挂起的I/O请求不再被取消。这是一个深奥的设计,不再需要了。