信号线程上的 WaitForSingleObject 给出 WAIT_FAILED,为啥?

Posted

技术标签:

【中文标题】信号线程上的 WaitForSingleObject 给出 WAIT_FAILED,为啥?【英文标题】:WaitForSingleObject on signalled thread gives WAIT_FAILED, why?信号线程上的 WaitForSingleObject 给出 WAIT_FAILED,为什么? 【发布时间】:2014-12-18 19:00:21 【问题描述】:

我有一个多线程代码,其重置线程定义为:

bool CTestShellDlg::ResetThreads()

//if Main worker thread already finished, Just Reset
    if (CheckMainThreadFinished())
    
        //reset
    
    else 
        if(KillThreads())  //Go ahead and reset if killing is finished.
        
            //reset
        
    else
        return false; //killing already in progress. gotta wait!

而KillThreads()定义为:

bool CTestShellDlg::KillThreads()

//if killing not already in progress
if (!CheckKillEvent())


    //Signall the killing event
    SetEvent(h_KillEvent);

    if (WaitMainThreadFinished())
    
        //call some deletes
        //Reset the kill event back to non-signalled to indicate it's no longer in progress
        ResetEvent(h_KillEvent);
        return true; //Killing successful
    
    else IERROR

else
    return false; //Killing already in progress

bool WaitMainThreadFinished()WaitForSingleObject(m_hDoIt_Thread, INFINITE);...
bool CheckMainThreadFinished()WaitForSingleObject(m_hDoIt_Thread, 0);...

现在,我可以很好地调用 KillThreads()。在这个过程中,我 WaitForSingleObject(m_hDoIt_Thread, INFINITE) 所以我知道到最后,它肯定是有信号的。现在,如果我尝试调用 ResetThreads(),我在 CheckMainThreadFinished() 中的 WaitForSingleObject(m_hDoIt_Thread, 0) 给了我 WAIT_FAILED,而在我的理解中它应该是 WAIT_OBJECT_0。什么可能导致这种情况? 有什么有趣的。是不是如果我连续进行两次 ResetThreads() 调用,我就不会从 CheckMainThreadFinished() 获得所述返回值。

【问题讨论】:

【参考方案1】:

修好了! 使用 GetLastError() ,结果是

的句柄
WaitForSingleObject(m_hDoIt_Thread, 0);

无效。原因是默认情况下,MFC 线程在退出时释放其线程句柄并删除线程对象。这会给您留下无效的线程指针和句柄,因此这种检查主句柄是否工作的方法将不起作用,应该使用替代方法。

【讨论】:

仅供参考:您可以将 mb_AutoDelete 设置为 FALSE 你提到的有趣的事情!事实上,我设置了 mb_AutoDelete=False 来保留指针和句柄。如何删除实际完成的线程?终止线程? 不要使用 TerminateThread。不建议使用。阅读有关它的 MSDN。 m_bAutoDelete 仅适用于 CWinThread 对象。如果您使用 m_bAutoDelete = FALSE 创建了线程,则需要存储 CWinThread 对象的指针并在线程完成后将其删除 澄清一下,“子”工作线程 m_bAutoDelete=false,而调用这些线程的“父”工作线程默认使用它,这就是我的 CheckMainThreadFinished() 失败的原因。所以是的,我确实有指向这些线程的指针。但是如何删除实际的线程,而不是指向它们的指针呢? 那么 m_bAutoDelete 的唯一意义就是保持指针和句柄活着?那么在“已完成”线程中定义的所有变量都会在它完成时被删除?

以上是关于信号线程上的 WaitForSingleObject 给出 WAIT_FAILED,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

多个线程上的信号量和临界区问题

如何通过 PySide 上的另一个线程从 QMainWindow 类中捕获信号?

gdb调试Alpine Linux上的OpenJDK java失败了“线程接收信号?,未知信号”

信号未从线程传递到 GUI

信号化线程以启动特定功能

信号是不是保证到达线程?