2010-08-05 207 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