2013-03-12 22 views
2

使用Borland/Embarcadero TClientSocket組件,我遇到了明顯的手柄泄漏。我有一個應用程序創建多個TThread實例,每個實例動態創建一個TClientSocket對象,連接到它的目標發送幾條消息,然後被刪除。然後刪除TThread實例(使用FreeOnTerminate = true)設置。我知道這是效率低下的,但它完全適合應用程序的需求 - 同時存在的最大數量限制爲32.我看到的問題是存在明顯的窗口句柄泄漏問題,我可以通過任務管理器查看。爲了解決這個問題,我在單線程意義上應用了相同的問題,只需動態創建一個對象並在主VCL線程的單個循環內完成時再次刪除它。這表現出相同的手柄泄漏問題。我知道該組件已被棄用,我知道我正在做的是低效率的,但我不明白爲什麼會出現句柄泄漏。在刪除這個句柄泄漏之前,有沒有什麼需要用TClientSocket對象完成,或者這是組件中的錯誤?我在非阻塞模式下使用套接字並將事件處理程序分配到OnConnectOnDisconnectOnSocketError使用多個TClientSocket實例導致Windows Handle泄漏的C++應用程序

+0

SO_LINGER也許?只是在這裏猜測。如果是這樣的話,我會感到驚訝,因爲這將是意想不到的,但是如果你能夠在底層套接字上獲得細粒度的控制,值得一提。 – WhozCraig 2013-03-12 21:33:31

+0

@WhozCraig:'SO_LINGER'與手柄無關。但是,可以通過TClientSocket(通過'TClientSocket.Socket.SocketHandle'屬性)訪問底層的'SOCKET'句柄,並直接調用WinSock API函數,如'setsockopt()'。 – 2013-03-13 05:22:24

+0

@RemyLebeau該插座後面是否沒有IO手柄?即,如果我打開10,000個套接字並啓動procexp,我*不會*看到處理計數比例?我只是提出它,因爲我有一個類似的問題與大容量快速卸載應用程序,這正是問題。在斷開連接之後,不會中斷計時器,手柄不會立即返回。正如我所說的,我遵循更多的知識,這看起來像你。謝謝(你的)信息。 – WhozCraig 2013-03-13 05:26:27

回答

1

我已經使用了TClientSocket多年,包括在主線程和工作線程中的使用情況,並且我從未見過TClientSocket泄漏任何句柄。

然而,TClientSocket不會默認爲非阻塞模式,在此模式下,使用AllocateHWnd()創建一個隱藏的窗口接收套接字事件,並AllocateHWnd()不是線程安全。沒有看到您的實際代碼,這是您在工作線程代碼中看到的泄漏的可能原因。解決這個問題的方法就是不使用TClientSocket在工作線程中使用時是非阻塞模式。改爲在阻塞模式下使用它。無論如何,它更適合基於線程的邏輯。

但是,這並不能解釋您在主線程代碼中看到的泄漏。我懷疑TClientSocket實際上是罪魁禍首,再一次,沒有看到你的實際代碼,很難肯定地說。

+0

感謝您的回覆。我只是看看Embarcadero的'AllocateHWnd()'文檔 - 根據你所說的話,這也意味着在線程中使用'TTimer'對象也是不安全的? – mathematician1975 2013-03-13 07:56:36

+0

@ mathematician1975:是的,'TTimer'確實使用'AllocateHWnd()',所以'TTimer'在工作線程中也不安全。但是線程定時器有更好的選擇,比如'CreateWaitableTimer()'。 – 2013-03-13 16:42:15

+0

感謝您的信息。我想我會重寫所有使用阻塞客戶端的東西。 – mathematician1975 2013-03-13 17:16:10

相關問題