2013-01-22 26 views
1

一點背景:如何回收由RPC運行時分配的線程句柄?

我正在使用RPC通過網絡進行通信的Windows程序。網絡連接不斷斷開。 RPC調用是同步的,但有多個客戶端線程同時運行。這些程序是對稱的 - 也就是說,雙方作爲客戶端和服務器,並運行完全相同的軟件。它使用標準的Windows API在C++中實現。

問題:

線程的句柄數通過隨時間進程瀏覽器增加的報道。看來線程是由RPC運行時處理請求產生的,但是線程回收時並不總是清理這些句柄。

這個數字會增加,特別是當有很多數據被傳輸時,或者當有很多呼叫同時發生時(這兩個因素同時出現,我不確定哪一個是相關的)。

一個活動服務器可以在幾天內建立幾千個未使用的線程句柄,而在任何時候都不會使用超過20個線程。

問題:

我能做些什麼,以保持句柄計數從安裝,因爲我相信它可以在客戶站點會導致穩定性問題?

+0

[使用I/O完成端口在MFC中編寫Windows NT Server應用程序](http://msdn.microsoft.com/en-us/library/ms810436.aspx) – sergmat

回答

0

那麼,令人驚訝的是,即使線程終止,也不會釋放所有資源。你必須在你從beginthreadex收到的線程句柄上調用CloseHandle()或者調用什麼東西。另外,不要(!!!)使用CreateThread(),請參閱MSDN文檔。

還有一件事情,雖然這不會導致你的問題,這是線程永久的開始和終止。相反,使用線程池。此外,但這取決於您的實際設置,每個網絡接口只需一個線程即可執行IO,而每個CPU只需一個線程即可執行計算。使用線程池,可以輕鬆限制這個數字。保持這些在控制下應該限制線程創建/清除和上下文切換引起的開銷。如果連接在網絡IO,CPU和可能的磁盤IO甚至UI之間切換很多,這並不總是可行的。

+0

問題是我不是那個打開這些線程 - 這些都是由RPC運行時在幕後處理的。但是,我可以在遠程函數關閉之前嘗試調用CloseHandle(),看看會發生什麼。值得一試 - 感謝這個想法! – TheWalruss

+0

不,線程似乎不可能爲自己關閉現有的句柄 - 另一種方法是複製句柄並關閉句柄,但如預期的那樣,完全沒有任何作用。 RPC運行時似乎使用線程池,因爲我經常看到線程被「重用」用於不同的調用。 我現在要通過調用AfxEndThread()來實驗,而不是從遠程調用返回 - 可能會更好地清理問題。 – TheWalruss

+0

AfxEndThread()沒有改善問題。 – TheWalruss