我正在开发一个应用程序,它有一个TCP服务器和几个UDP服务器/侦听器。每台服务器都是一个单独的线程,与已建立TCP连接的工作线程相同。我在每个线程中调用WSAStartup()。
有时,调用WSAStartup()会挂起(在我看来这是一个死锁)。下面是堆栈跟踪:
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_ZwWaitForSingleObject@12() + 0xc bytes
ntdll.dll!_RtlpWaitForCriticalSection@4() + 0x8c bytes
ntdll.dll!_RtlEnterCriticalSection@4() + 0x46 bytes
ntdll.dll!_LdrpGetProcedureAddress@20() + 0x17d bytes
ntdll.dll!_LdrGetProcedureAddress@16() + 0x18 bytes
kernel32.dll!_GetProcAddress@8() + 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
ws2_32.dll!_WSAStartup@8() + 0xa7 bytes
这种死锁发生在初始化故障期间。我看到TCP服务器启动了,并且建立了一个TCP连接,而只启动了一个UDP服务器。堆栈跟踪来自应启动其余UDP服务器的函数。我的猜测是,当我试图初始化UDP服务器并调用WSACStartup()时,另一个tread正在处理另一个套接字操作,例如一个新的TCP连接,它也在调用WSAStartup()?
我的问题是,从多个线程调用WSAStartup()是否会导致这种死锁?我还检查了在死锁之前调用的WSACleanup(),但它不是。执行永远不会到达任何WSACleanup()。
我知道只调用一次WSAStartup就足够了,但是多次调用WSAStartup()应该不是问题(MSDN]1:“如果应用程序需要多次获取WSAStartup结构信息,那么它可以多次调用WSADATA。”因此,我想确定这个死锁是由WSAStartup()还是其他原因引起的。
发布于 2013-10-04 06:44:29
WSAStartup函数通常导致加载特定于协议的帮助器DLL。因此,不应从应用程序DLL中的DllMain函数调用WSAStartup函数。这可能会导致死锁。Dllmain在DLL加载器临界区被调用,这是导致此死锁的主要原因。
有关更多细节,请访问:http://msdn.microsoft.com/en-us/library/windows/desktop/ms742213%28v=vs.85%29.aspx
发布于 2010-08-06 02:41:41
您根本不必多次调用WSAStartup()
。每个程序一次就可以了。
发布于 2010-08-06 03:10:18
我认为卢克是对的。不能在DllMain()或全局/静态变量的初始值设定项中调用WSAStartup()。更改您的代码,使其不会发生。
https://stackoverflow.com/questions/3417579
复制相似问题