2010-08-05 16 views
5

Zajmuję się tworzeniem aplikacji, która ma jeden serwer TCP i kilka serwerów/detektorów UDP. Każdy serwer jest osobnym wątkiem, tak samo jak wątki robocze dla ustalonych połączeń TCP. Nazywam WSAStartup() w każdym wątku.Czy wywołanie funkcji WSAStartup() z kilku wątków może spowodować zakleszczenie?

Czasami wywołanie funkcji WSAStartup() zawiesza się (dla mnie wygląda jak zakleszczenie). Oto ślad stosu:

[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 

Ten impas występuje podczas fazy inicjalizacji. Widzę, że serwer TCP został uruchomiony i że ustanowiono jedno połączenie TCP, podczas gdy uruchamiany jest tylko jeden z serwerów UDP. Śledzenie stosu pochodzi z funkcji, która powinna zainicjować pozostałe serwery UDP. Zgaduję, że podczas gdy próbuję zainicjować serwer UDP i wywołanie funkcji WSACStartup(), inny bieżnik obsługuje inną operację na gnieździe, na przykład nowe połączenie TCP, a także wywołuje funkcję WSAStartup()?

Moje pytanie brzmi, czy wywołanie funkcji WSAStartup() z kilku wątków może spowodować ten zakleszczenie? Sprawdziłem również WSACleanup() wywołana przed impasem, a nie jest. Wykonanie nigdy nie osiąga żadnego z WSACleanup().

Zdaję sobie sprawę, że tylko jedno wywołanie funkcji WSAStartup powinno wystarczyć, ale nazywając WSAStartup (kilka razy) nie powinno być problemem (MSDN] 1): „Aplikacja może wywołać WSAStartup więcej niż jeden raz, jeśli to konieczne uzyskać więcej informacji o strukturze WSADATA więcej niż jeden raz. " Dlatego chciałbym ustalić, czy ten impas jest spowodowane przez WSAStartup() lub coś innego.

+0

To nie jest odpowiedź na pytanie, ale czy należy rozważyć użycie doładowania ASIO (http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio.html)?Miałem o wiele łatwiejsze rozwiązanie problemów takich jak twoja z tą biblioteką. – nabulke

+0

Nikolai, użyłem doładowania przed i lubię to. Odkąd uruchomiłem tę aplikację z WinSock, chciałbym przejść do sedna tego problemu. Po prostu ciekawy chyba :) –

+0

Czy patrzyłeś na stosy połączeń innych wątków? –

Odpowiedz

2

Nie musisz wielokrotnie dzwonić pod numer WSAStartup(). Raz na program jest w porządku.

+1

Imho, pytanie jasno stwierdza, że ​​starter tematu przeczytał tę część MSDN i zamiast rozwiązania "omijać" problem (który jest zdecydowanie dobrym rozwiązaniem) - próbuje znaleźć główną przyczynę. – Andrey

+0

To jak stary żart: "Doktorze, boli, kiedy to robię". "Więc nie rób tego." –

+1

Należy go wywołać na bieżniku, który tworzy gniazdo. – rxantos

0

Myślę, że Łukasz ma rację. Nie można wywołać metody WSAStartup() w DllMain() ani w inicjalizatorach zmiennych globalnych/statycznych. Zmień swój kod, aby tak się nie stało.

+0

Pracuję na samodzielnej aplikacji i używam systemowych bibliotek DLL, dlatego nie mam DLLMain(). Wszystkie moje wywołania funkcji WSAStartup() są w funkcjach wątków: http://msdn.microsoft.com/en-us/library/ms686736(VS.85).aspx PS. tutaj jest lista dodatkowych bibliotek: - ws2_32.lib - strsafe.lib - shell32.lib –

+0

Przyjrzyj się bliżej liście bibliotek DLL załadowanych do wersji "release" twojej aplikacji (bez profilerów, wykrywaczy nieszczelności itp.). Istnieje szansa, że ​​jedną z tych bibliotek DLL jest przechwytywanie funkcji Windows. Eksplorator procesów SysInternals bardzo ci pomoże. – Andrey

0

WSAStartup faktycznie nie prowadzą do LoadLibrary jakiegokolwiek rodzaju, więc nie czuję się jakby to loader lock przypadek.

Zamiast tego jest oczywiste, że Windows API jest uwięziony w twoim przypadku (termin trap jest tutaj lepszy, ponieważ hook ma inne znaczenie w Windows).

W związku z tym uważam, że problemem nie jest jednoczesne korzystanie z WSAStartup, ale w efektach ubocznych pułapek innych firm nad oryginalnymi funkcjami interfejsu Windows API w procesie. Myślę, że musisz oczyścić swoje środowisko z wszelkich zewnętrznych wpływów (pułapki api z twojej strony lub z oprogramowania antywirusowego, cokolwiek).

Nawiasem mówiąc, upewnij się, że każdy wątek twój zapewnia WSAStartup z własną oddzielną kopię parametru wyjściowego WSAData

+1

Czy jesteś pewien, że nie wykonuje ** wywołania LoadLibrary **? –

+0

Masz rację, nie pamiętam, dlaczego tak myślałem, ale w rzeczywistości mogę załadować biblioteki pomocnicze według MSDN - w ten sposób problem może stanowić blokada programu ładującego. Nadal uważam, patrząc na stos, podstawową przyczyną jest pułapka przechwytująca WSAStartup. – Andrey

3

Funkcja WSAStartup zazwyczaj prowadzi do konkretnych protokołów pomocnika DLL jest załadowany. W rezultacie funkcja WSAStartup nie powinna być wywoływana z funkcji DllMain w bibliotece DLL aplikacji. Może to potencjalnie powodować zakleszczenia. Dllmain jest wywoływany w sekcji krytycznej modułu ładującego biblioteki DLL, która jest główną przyczyną tego impasu.
Aby uzyskać więcej informacji: http://msdn.microsoft.com/en-us/library/windows/desktop/ms742213%28v=vs.85%29.aspx

Powiązane problemy