【发布时间】:2013-05-29 09:51:28
【问题描述】:
我有一个使用 TCP (Winsock API) 和 HTTP (WININET API) 套接字的应用程序。这是一个多线程应用程序,我有一种情况,当出现网络故障时,我会调用一个重新连接线程(有一个 while 循环,虽然休眠了几秒钟,每个都用于 tcp reconnect 和 http reconnect - 基本上是尝试套接字连接)。当 tcp reconnect thread 和 http reconnect thread 在一段时间后运行时,tcp reconnect thread 到达此行:
TCP 重连线程:
DWORD WINAPI MyThreadProc ( LPVOID lParam )
{
printf ( "In MyThreadProc" ) ;
// Code
return 1 ;
}
hSampleHandle = CreateThread ( 0 , 0 (LPTHREAD_START_ROUTINE)MyThreadProc, this , 0 , &threadId ) ;
HTTP 重新连接线程:
DWORD WINAPI MyHttpThreadProc ( LPVOID lParam )
{
printf ( "In HTTP Reconnect" ) ;
// Code
return 1 ;
}
hHttpReq = CreateThread ( 0 , 0 , MyHttpThreadProc , this , 0 , &ThreadId ) ;
我检查 hSampleHandle 返回值,它不是 NULL 我也得到一个 threadId 。但是 MyThreadProc 没有被调用。然后我执行 WaitForSingleObject which timeout 。我真的很想知道这种行为的原因是什么?
更新: 1)注释掉 MyHttpThreadProc 中的代码后,我无法重现该错误。所以很明显,winsock 和 wininet 实现之间共享了一些资源,导致了这种奇怪的行为。
2)我尝试冻结 HTTP 重新连接线程(来自 Visual Studio 2012 中的 ThreadWindow),并且 TCP 重新连接线程工作正常。这导致了以下探测:
P.S : 1) 这两者在应用程序级别之间没有共享资源。
2) 我怀疑死锁并继续在 windbg(用户模式死锁)中进行调试,它显示了 9 个关键部分,但所有 9 个部分的 lockcount 值都未锁定。
3) 我的另一个怀疑是WINSOCK & WININET 一起使用。我知道他们都使用 mswsock.dll 并且它可能是导致内核死锁的加载程序锁吗?在发布 !kdexts.locks 时,我遇到了一些错误,所以我没有深入研究。
4) 这是否属于线程冻结类别?有人可以解释这种行为。
5) 这个http://www.cpptalk.net/threadproc-does-not-run-when-createthread-is-called-within-vt7735.html 在这里没有用,因为我不使用单独的 dll。
【问题讨论】:
-
我会首先解决必须强制转换函数指针的原因 - 这通常是错误的标志。如果没有更多信息,我们真的无法为您提供帮助,我的水晶球今天早上刚刚破裂。创建Short, Self Contained, Correct Example
-
请张贴
MyThreadProc的声明。 -
显示更多代码。我看到的唯一问题是不必要的(和危险的)演员表。您不会导致来自用户空间的内核死锁。在 windbg 中,发出 ~ 命令以列出所有线程。你能看到你的吗?用 ~nk 打印它的堆栈,其中 n 是线程号。
-
这里少了一个逗号:
CreateThread ( 0 , 0 (LPTHREAD_START_ROUTINE)MyThreadProc, -
@Voo:你是对的。不必要的铸造。我删除了它,但问题仍然存在。
标签: c++ multithreading thread-safety deadlock winsock2