1 つの 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 接続が 1 つ確立されていることがわかりますが、UDP サーバーは 1 つしか開始されていません。スタック トレースは、残りの UDP サーバーを開始する関数からのものです。私の推測では、UDP サーバーを初期化して WSACStartup() を呼び出している間に、別のトレッドが別のソケット操作 (新しい TCP 接続など) を処理しており、WSAStartup() も呼び出しているのではないでしょうか?
私の質問は、複数のスレッドから WSAStartup() を呼び出すと、このデッドロックが発生する可能性があるかどうかです。また、デッドロックの前に呼び出された WSACleanup() を確認しましたが、そうではありません。実行は WSACleanup() のいずれにも到達しません。
WSAStartup を 1 回呼び出すだけで十分であることは承知していますが、WSAStartup() を数回呼び出すことは問題にならないはずです (MSDN] 1 ):「アプリケーションは、WSADATA 構造情報を取得する必要がある場合、WSAStartup を複数回呼び出すことができます。一回以上。" したがって、このデッドロックが WSAStartup() によって引き起こされているのか、それとも他の何かによって引き起こされているのかを確認したいと思います。