I / O的最新Windows线程池API使用情况

我不明白最新的Windows线程池API的一部分。 我需要帮助。

从文档中,用于I / O(在我的情况下,用于SOCKET)的配方可以总结如下:

  1. 调用CreateThreadpoolIo。
  2. 调用StartThreadpoolIo 。 你可以在这里find这个警告:

    在启动与I / O完成对象绑定的文件句柄上的每个asynchronousI / O操作之前,您必须调用此函数。 如果不这样做,将导致线程池在完成时忽略I / O操作,并导致内存损坏。

  3. 调用文件句柄上的操作(例如,WSARecvFrom)。 如果失败,请致电CancelThreadpoolIo 。 否则,在可用时处理结果。 WSARecvFrom在asynchronous使用时,会要求WSAOVERLAPPED(您必须事先创build),但不要将其链接到之前调用StartThreadpoolIo的任何信息。 CancelThreadpoolIo只请求PTP_IO,但不要求任何附加信息来派生特定的asynchronous操作。
  4. 重复步骤2和3。
  5. 调用CloseThreadpoolIo来完成。 你可以在这里find这个警告:

    可能需要取消线程池I / O通知以防止内存泄漏。 有关更多信息,请参阅CancelThreadpoolIo。

我通常需要它的UDP,所以我努力在任何给定的时间排队几个接收操作(asynchronousWSARecvFrom操作开始)。 这样,我不必急于在callback函数开始时开始另一个接收操作,也不需要同步对接收缓冲区的访问(我可以有一个池,每个都可以包含一个数据报,并重新发出接收操作当我完成每个消息的处理;在此期间,其他排队的操作将保持接收器繁忙)。 数据报是独立自主的。 我知道这种方法可能对TCP无效。

StartThreadpoolIo / CancelThreadpoolIo似乎是问题的根源:StartThreadpoolIo和WSARecvFrom没有直接绑定(它们不共享任何参数)。 所以:

当您调用CancelThreadpoolIo时,框架如何知道要取消哪个操作? 它是如何取消失败的操作而不是任何挂起的操作?

你可以说,“不要同时调用StartThreadpoolIo”。 我可以没有几个并发WSARecvFrom的生活,但我不能没有并发WSARecvFrom和WSASendTo。 所以我认为无法同时进行多个asynchronous操作不能成为API的devise方式。

你可以说,“只调用StartThreadpoolIo一次,这将足以注册callback,这是一个开/关过程”。 但是文档说:

您必须在启动文件句柄上的每个asynchronousI / O操作之前调用此函数。

你可以说,“它取消了刚才调用StartThreadpoolIo的同一线程启动的操作。 但是,在调用CloseThreadpoolIo的上下文中调用CancelThreadpoolIo的build议没有任何意义(我将从触发停止的线程中调用CloseThreadpoolIo,这将完全独立于发出asynchronous操作的线程;并且一次调用CancelThreadpoolIo可能会不足以取消几个操作)。 无论如何,无法从不同的线程触发取消是一个严重的限制。 我知道CreateThreadpoolCleanupGroup的存在,但我的问题是更根本的。 我想了解这个API如何从根本上是正确和有用的。

你可以说“多次调用CreateThreadpoolIo,这样你就有了独立的PTP_IO”。 它不起作用。 当我第二次调用CreateThreadpoolIo时,返回nullptr。

我错了,还是这个API尴尬? 通常,其他asynchronousAPI可以使用以下模式之一:

  1. 创build一个操作并接收一个句柄=>调用传递该句柄的方法。
  2. 创build一个可重用的句柄=>调用方法(包括启动操作)传递句柄。

最新的Windows线程池API,其中句柄似乎是隐含的,或者有相同操作的几个句柄(TP_IO,WSAOVERLAPPED,StartThreadpoolIo),它们并不是全部显式地链接在一起,都不使用它们。

非常感谢您的帮助。

当您调用CancelThreadpoolIo时,框架如何知道要取消哪个操作? 它是如何取消失败的操作而不是任何挂起的操作?

CancelThreadpoolIo()不取消IO。 StartThreadpoolIo()是相反的。 StartThreadpoolIo()准备线程池来接受完成。 如果线程池不期望完成,它不会等待它,因此您可能会错过它。 如果线程池期望完成但没有完成,线程池可能浪费资源。

CancelThreadpoolIo()撤销StartThreadpoolIo()所做的任何操作。