5

Ich entwickle eine App, die einen TCP-Server und mehrere UDP-Server/Listener hat. Jeder Server ist ein separater Thread, genauso wie die Worker-Threads für etablierte TCP-Verbindungen. Ich rufe WSAStartup() in jedem der Threads auf.Kann Aufruf von WSAStartup() aus mehreren Threads einen Deadlock verursachen?

Manchmal hängt Aufruf von WSAStartup() (es sieht für mich wie ein Deadlock aus). Hier ist der Stack-Trace:

[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 

Dieser Deadlock geschieht während der Initialisierung faze. Ich sehe, dass der TCP-Server gestartet wird und dass eine TCP-Verbindung hergestellt wird, während nur einer der UDP-Server gestartet wird. Der Stack-Trace stammt von der Funktion, die den Rest der UDP-Server initiieren soll. Meine Vermutung ist, dass, während ich versuche, UDP-Server zu initieren und WSACStartup() aufzurufen, ein anderes Profil eine andere Socket-Operation behandelt, zum Beispiel eine neue TCP-Verbindung, und es ruft auch WSAStartup() auf?

Meine Frage ist, ob Aufruf von WSAStartup() aus mehreren Threads diesen Deadlock verursachen kann? Auch überprüft habe ich die WSACleanup() vor dem Deadlock aufgerufen, und es ist nicht. Die Ausführung erreicht niemals WSACleanup().

Ich bin mir bewusst, dass nur ein Aufruf an WSAStartup genug sein sollte, noch ruft WSAStartup (mehrmals) sollte kein Problem (MSDN] 1) sein: „Eine Anwendung aufrufen kann mehr als einmal WSAStartup wenn es braucht, um Erhalten Sie die WSADATA-Strukturinformationen mehr als einmal. " Daher möchte ich feststellen, ob dieser Deadlock durch WSAStartup() oder etwas anderes verursacht wird.

+0

Das ist keine Antwort auf Ihre Frage, aber finden Sie Boost Asio mit (http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio.html)Ich hatte viel leichter Probleme mit der Bibliothek zu lösen. – nabulke

+0

Nikolai, ich habe den Boost vorher benutzt und mag es. Seit ich diese App mit WinSock gestartet habe, möchte ich dem Thema auf den Grund gehen. Nur zu neugierig, denke ich :) –

+0

Hast du die Callstacks deiner anderen Threads angeschaut? –

Antwort

2

Sie müssen WSAStartup() nicht mehrmals aufrufen. Einmal pro Programm ist in Ordnung.

+1

Imho, Frage besagt eindeutig, dass Thema Starter hat diesen Teil von MSDN gelesen und anstelle der Lösung zu "vermeiden" das Problem (das ist definitiv eine gute Lösung) - er versucht, die Ursache zu finden. – Andrey

+0

Es ist wie der alte Witz: "Doktor, es tut weh, wenn ich das tue." "Also tu das nicht." –

+1

Es muss an der Lauffläche, die die Steckdose erstellt aufgerufen werden. – rxantos

0

Ich denke, dass Lukas Recht hat. Sie können WSAStartup() nicht in DllMain() oder Initialisierer von globalen/statischen Variablen aufrufen. Ändern Sie Ihren Code, damit es nicht passiert.

+0

Ich arbeite an einer eigenständigen Anwendung und ich verwende System-DLLs, daher habe ich keine DLLMain(). Alle meine Aufrufe an WSAStartup() sind in den Thread-Funktionen: http://msdn.microsoft.com/en-us/library/ms686736(VS.85).aspx PS. Hier ist die Liste der zusätzlichen Bibliotheken: - ws2_32.lib - strsafe.lib - shell32.lib –

+0

Werfen Sie einen Blick auf die Liste der DLLs in "Release" Version Ihrer Anwendung (ohne Profiler, Lecksucher , etc). Es besteht die Möglichkeit, dass eine dieser DLLs Windows-Funktionen abfängt. Der Process Explorer von SysInternals hilft Ihnen sehr. – Andrey

0

WSAStartup eigentlich nicht jeglicher Art zu Loadlibrary führen, so dass ich nicht das Gefühl, dass es ein loader lock Fall ist.

Stattdessen ist es offensichtlich, dass Windows-API in Ihrem Fall gefangen ist (Begriff trap ist hier besser, weil hook hat andere Bedeutung in Windows).

Daher glaube ich, dass das Problem nicht in der gleichzeitigen Verwendung von WSAStartup, sondern in Nebenwirkungen von Drittanbieter-Traps über Original-Windows-API-Funktionen in Ihrem Prozess ist. Ich denke, Sie müssen Ihre Umgebung von jeglichen externen Einflüssen säubern (API-Fallen von Ihrer Seite oder von Antivirensoftware, was auch immer).

By the way, stellen Sie sicher, dass jeder Faden von Ihnen mit einem eigenen separaten Kopie WSADATA Ausgangsparameter liefert WSAStartup

+1

Sind Sie sicher, dass es keinen Aufruf von ** LoadLibrary ** ausführt? –

+0

Sie haben Recht, ich erinnere mich nicht, warum ich damals so dachte, aber es kann tatsächlich Helfer-DLLs nach MSDN laden - daher könnte die Ladersperre ein Problem sein. Ich denke immer noch, wenn ich den Stapel ansehe, liegt die Ursache in einer Falle, die WSAStartup abgefangen hat. – Andrey

3

Die WSAStartup Funktion führt typischerweise zu protokollspezifische Helfer DLLs geladen werden. Daher sollte die WSAStartup-Funktion nicht von der DllMain-Funktion in einer Anwendungs-DLL aufgerufen werden. Dies kann möglicherweise Deadlocks verursachen. Dllmain wird im kritischen Abschnitt des DLL-Ladeprogramms aufgerufen, was der Hauptgrund für diesen Deadlock ist.
Für weitere Informationen: http://msdn.microsoft.com/en-us/library/windows/desktop/ms742213%28v=vs.85%29.aspx

Verwandte Themen