【问题标题】: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() 获得所述返回值。

【问题讨论】:

    标签: multithreading mfc thread-safety wait


    【解决方案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 的唯一意义就是保持指针和句柄活着?那么在“已完成”线程中定义的所有变量都会在它完成时被删除?
    猜你喜欢
    • 2010-09-17
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 2010-09-19
    相关资源
    最近更新 更多