C++ 如何回收RPC运行时分配的线程句柄?

C++ 如何回收RPC运行时分配的线程句柄?,c++,windows,multithreading,rpc,handles,C++,Windows,Multithreading,Rpc,Handles,一点背景: 我正在开发一个Windows程序,它使用RPC通过网络进行通信。网络连接持续进行并断开。RPC调用是同步的,但有多个客户端线程同时运行。程序是对称的——也就是说,双方都充当客户机和服务器,并且运行完全相同的软件。它是用C++实现的,使用标准的Windows API。 问题是: Process Explorer报告的线程句柄数会随着时间的推移而增加。RPC运行时似乎让线程来处理请求,但在回收线程时并不总是清理句柄 这个数字会增加,特别是当有大量数据传输时,或者当有许多电话同时发生时,这

一点背景:

我正在开发一个Windows程序,它使用RPC通过网络进行通信。网络连接持续进行并断开。RPC调用是同步的,但有多个客户端线程同时运行。程序是对称的——也就是说,双方都充当客户机和服务器,并且运行完全相同的软件。它是用C++实现的,使用标准的Windows API。 问题是:

Process Explorer报告的线程句柄数会随着时间的推移而增加。RPC运行时似乎让线程来处理请求,但在回收线程时并不总是清理句柄

这个数字会增加,特别是当有大量数据传输时,或者当有许多电话同时发生时,这两个因素是同时发生的,我不确定哪一个是相关的

一个活动服务器可以在几天内建立数千个未使用的线程句柄,而在任何时候都不会使用超过20个线程

问题是:


我可以做些什么来防止句柄计数增加,因为我相信这可能会导致客户站点的稳定性问题?

好吧,令人惊讶的是,即使线程终止,这也不会释放其所有资源。您必须对从beginthreadex收到的线程句柄或调用的对象调用CloseHandle。还有,不要!!!使用CreateThread,请参阅MSDN文档


还有一件事,尽管这不会引起您的问题,那就是线程的永久启动和终止。相反,使用线程池。而且,这取决于您的实际设置,对于IO,每个网络接口只需要一个线程,对于计算,每个CPU只需要一个线程。使用线程池,您可以轻松地限制此数量。保持这些控制应该限制线程创建/清理和上下文切换造成的开销。如果连接在网络IO、CPU和磁盘IO甚至UI之间频繁切换,这并不总是可行的。

问题是,我不是打开这些线程的人—所有这些都是由RPC运行时在幕后处理的。但是,我可以尝试在远程函数关闭之前调用CloseHandle,看看会发生什么。值得一试——谢谢你的主意!不,一个线程似乎不可能将现有的句柄关闭到它自己——另一种方法是复制一个句柄并关闭它,但是,正如预期的那样,这完全没有任何作用。RPC运行时似乎确实使用了线程池,因为我经常看到线程被用于不同的调用。我现在将通过调用AfxEndThread而不是从远程调用返回来进行实验——也许这样可以更好地清理问题。这很糟糕,如果RPC系统不重用线程,也不结束线程,那就是一个bug。在代码中唯一可能导致此问题的是,如果您试图永不返回,或者您试图以某种方式混淆RPC系统,例如通过抛出异常退出回调。尽量减少你在代码中所做的事情,看看它是否消失了。