2010-08-05 81 views
5

我正在開發一個具有一個TCP服務器和多個UDP服務器/偵聽器的應用程序。每個服務器都是獨立的線程,與建立TCP連接的工作線程相同。我在每個線程中調用WSAStartup()。從幾個線程調用WSAStartup()會導致死鎖嗎?

有時,調用WSAStartup()會掛起(它看起來像是一個死鎖)。以下是堆棧跟蹤:

[email protected]() 
    [email protected]() + 0xc bytes 
    [email protected]() + 0x8c bytes 
    [email protected]() + 0x46 bytes 
    [email protected]() + 0x17d bytes 
    [email protected]() + 0x18 bytes 
    [email protected]() + 0x3e bytes 
    vld.dll!03203723() 
    [Frames below may be incorrect and/or missing, no symbols loaded for vld.dll] 
    ws2_32.dll!CheckForHookersOrChainers() + 0x22 bytes 
    [email protected]() + 0xa7 bytes 

這種死鎖發生在初始化失敗期間。我看到TCP服務器已啓動,並且建立了一個TCP連接,而只有一個UDP服務器啓動。堆棧跟蹤來自應該啓動其餘UDP服務器的功能。我的猜測是,當我嘗試初始化UDP服務器並調用WSACStartup()時,另一個步驟是處理另一個套接字操作,例如新的TCP連接,它也調用WSAStartup()?

我的問題是,從幾個線程調用WSAStartup()是否會導致此死鎖? 另外我檢查的是死鎖之前調用的WSACleanup(),它不是。執行永遠不會達到任何WSACleanup()。

我知道,只有一個調用來調用WSAStartup應該是足夠的,但調用WSAStartup()幾次不應該是一個問題(MSDN] 1): 「應用程序可以調用調用WSAStartup不止一次是否需要多次獲取WSADATA結構信息。「 因此,我想確定這個死鎖是由WSAStartup()還是其他引起的。

+0

這是不回答你的問題,但你考慮使用升壓ASIO(http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio.html )?我有一個更容易的時間解決像你這樣的圖書館的問題。 – nabulke 2010-08-05 17:57:51

+0

尼古拉,我之前用過這個提升,喜歡它。自從我用WinSock開始這個應用程序之後,我想深入瞭解這個問題。只是爲了好奇我猜:) – 2010-08-05 18:30:15

+0

你看過你的其他線程的調用棧嗎? – 2010-08-05 18:33:42

回答

2

根本不需要多次撥打WSAStartup()。每個節目一次都好。

+1

Imho,問題清楚地表明,主題首發者已經閱讀了MSDN的這一部分,而不是解決方案來「避免」這個問題(這絕對是一個很好的解決方案) - 他試圖找到根本原因。 – Andrey 2010-08-05 21:24:22

+0

這就像那個老笑話:「醫生,當我這樣做的時候會感到痛苦。」 「那麼不要那樣做,那麼。」 – 2010-08-05 21:33:39

+1

它必須在創建插槽的胎面上調用。 – rxantos 2014-02-20 03:57:40

0

我認爲盧克是對的。您不能在DllMain()或全局/靜態變量的初始值設定項中調用WSAStartup()。改變你的代碼,使它不會發生。

+0

我正在開發一個獨立的應用程序,我正在使用系統DLL,因此我沒有DLLMain()。我所有對WSAStartup()的調用都在線程函數中: http://msdn.microsoft.com/en-us/library/ms686736(VS.85).aspx PS。以下是其他庫的列表: - ws2_32.lib - strsafe.lib - shell32.lib – 2010-08-05 20:40:11

+0

仔細查看加載到應用程序的「發佈」版本的DLL列表(不包括輪廓儀,泄漏檢測器等)。機會之一就是其中一個DLL陷阱窗口函數。 SysInternals的Process Explorer會幫助你很多。 – Andrey 2010-08-05 21:33:30

0

調用WSAStartup實際上並沒有導致調用LoadLibrary任何形式的,所以我不覺得這是一個loader lock情況。

相反,顯然windows API被困在你的案例中(術語trap在這裏更好,因爲hook在Windows中有其他含義)。

因此,我認爲問題不在於同時使用WSAStartup,而是在第三方陷阱中對原始Windows API函數的副作用進行處理。我認爲,您需要清除您的環境,避免受到任何外部影響(來自您身邊的api陷阱或防病毒軟件,無論如何)。

順便說一句,請確保您的每一個線程提供調用WSAStartup與WSADATA輸出參數

+1

你確定它不會執行** LoadLibrary **調用嗎? – 2014-07-31 19:45:27

+0

你是對的,我不記得我爲什麼那麼回想,但它實際上可以根據MSDN加載助手DLL - 因此加載程序鎖定可能是一個問題。我仍然認爲,看着堆棧,根本原因在於攔截WSAStartup的陷阱。 – Andrey 2014-08-06 00:22:23