我不了解最新的Windows threadpool API的一部分。我需要帮助。
从文档中,将其用于I / O的配方(在我的情况下,用于SOCKET)可归纳如下:
在对绑定到I / O完成对象的文件句柄启动每个异步I / O操作之前,必须调用此函数。如果不这样做,将导致线程池在完成时忽略I / O操作,并导致内存损坏。
可能需要取消线程池I / O通知以防止内存泄漏。有关更多信息,请参阅CancelThreadpoolIo。
我通常需要它用于UDP,因此我努力在任何给定时间排队几个接收操作(异步WSARecvFrom操作已启动)。这样我就不必急于在回调函数的开头开始另一个接收操作,也不必同步访问接收缓冲区(我可以有一个池,每个都可以包含一个数据报,并重新发出当我完成处理每条消息时的接收操作;在此期间,其他排队的操作将使接收器保持忙碌状态。数据报是独立的,自包含的。我知道这种方法可能对TCP无效。
StartThreadpoolIo / CancelThreadpoolIo在我看来问题的根源:StartThreadpoolIo和WSARecvFrom没有直接绑定(他们不共享任何参数)。所以:
当您调用CancelThreadpoolIo时,框架如何知道取消哪个操作?它如何取消失败的操作而不取消任何待处理的操作?
你可以说,"不要同时调用StartThreadpoolIo"。我可以在没有多个并发WSARecvFrom的情况下生活,但我不能在没有并发WSARecvFrom和WSASendTo的情况下生活。所以我认为无法同时进行多个异步操作可能不是API的设计方式。
你可以说,"只调用一次StartThreadpoolIo,这足以注册回调;这是一个开/关过程"。但文件说:
在启动文件句柄上的每个异步I / O操作之前,必须调用此函数...
你可以说,"它取消了刚刚调用StartThreadpoolIo"的同一个线程启动的操作。但是在调用CloseThreadpoolIo的上下文中调用CancelThreadpoolIo的建议没有意义(我将从触发停止的线程调用CloseThreadpoolIo,这将完全独立于发出异步操作的线程;以及单个调用CancelThreadpoolIo可能不足以取消多个操作)。无论如何,无法从不同的线程触发取消是一个严重的限制。我知道CreateThreadpoolCleanupGroup的存在,但我的问题更为基础。我想了解这个API如何从根本上说是正确和有用的。
您可以说"多次调用CreateThreadpoolIo,这样您就可以使用独立的PTP_IO来处理"。它不起作用。当我第二次调用CreateThreadpoolIo时,返回nullptr。
我错了,或者这个API有尴尬吗?通常,其他异步API使用以下模式之一:
最新的Windows线程池API,其中句柄似乎是隐式的,或者有相同操作的多个句柄(TP_IO,WSAOVERLAPPED,StartThreadpoolIo)并且它们都没有明确地链接在一起,它们都不使用它们
非常感谢你的帮助。
答案 0 :(得分:1)
当你调用CancelThreadpoolIo时,框架如何知道要取消哪个操作?它如何取消失败的操作 而不是任何待定的?
CancelThreadpoolIo()不取消IO。它与StartThreadpoolIo()相反。 StartThreadpoolIo()准备线程池以接受完成。如果线程池没有预期完成,它就不会等待它,因此你可能会错过它。如果线程池期望完成但完成没有发生,则线程池可能会浪费资源。
CancelThreadpoolIo()取消了StartThreadpoolIo()所做的任何事情。