【问题标题】:c++ ThreadProc not Invoked inspite of CreateThread Succeeding尽管 CreateThread Succeeding,但 c++ ThreadProc 未调用
【发布时间】: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


【解决方案1】:

到目前为止,似乎是 Http 线程实现(单独运行时)中的一个挂起,其中 Wininet dll 加载会导致线程挂起/冻结。如果 http 中的挂起已修复并模拟了类似的行为,则将重新打开该问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2021-11-27
    • 2020-11-19
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    相关资源
    最近更新 更多