【问题标题】:Thread is created but not executed线程已创建但未执行
【发布时间】:2020-03-26 10:38:20
【问题描述】:

我有一个供 ATL-COM 组件使用的 DLL。在我的 DLL 中,从 FinalConstruct 调用 StartMonitoring 方法。我想在 StartMonitoring() 中创建后台线程,但是创建了线程并返回了一个有效的句柄,但线程内的代码永远不会被执行。这是否与 ATL 组件的工作方式有关?如果这是一个愚蠢的问题,请原谅我,但我没有任何 ATL/COM 理解。

我认为这与 COM 的工作方式有关。在我的情况下,我需要 StartMonitoring 来启动一个后台线程,当从 FinalRelease() 调用 StopMonitoring 时,会发出这个后台线程退出的信号,然后等待它退出。现在因为线程没有启动但已经给出了一个有效的句柄,StopMonitoring 将发出信号并永远等待。如果我绕过Wait强行结束StopMonitoring并返回FinalRelease(),MonitorThreadProc然后开始执行。

unsigned int WINAPI CMonitor::MonitorThreadProc(LPVOID lpvParam)
{
    std::cout << "Enter MonitorThreadProc" << endl;   //Never hits this
    if (lpvParam == nullptr)
        return 1;

    CMonitor *pMonitor = static_cast<CMonitor*>(lpvParam);
    return (unsigned int)pMonitor->Run();
}

void CMonitor::StopMonitoring()
{

    if(m_EvtReg)
    {
        m_EvtStopMonitoring.Set();
        DWORD dwResult = ::WaitForSingleObject(m_hThread, INFINITE);
        if(dwResult == WAIT_OBJECT_0)
        {
            cout<<"Thread terminated"<<endl;
        }

    }
    m_EvtReg.Close();
    m_EvtStopMonitoring.Close();
    HANDLE h = m_hThread.Detach();
    CloseHandle(h);
}

bool CMonitor::StartMonitoring()
{

    int num = 0;
    unsigned int nThreadId = 0;
    HANDLE hThread = (HANDLE)_beginthreadex(nullptr, 0, MonitorThreadProc, (LPVOID)this, 0, &nThreadId);
    if(hThread == nullptr)
    {
        return false;
    }
    //I get a valid handle from _beginthreadex, but the thread never gets executed.
    m_hThread.Attach(hThread);
    return true;
}

【问题讨论】:

  • 任何机会StartMonitoringDllMain 调用
  • @rustyx 问题不在于 _beginthreadex,我在大量代码中使用过它,而不是新事物。在这里,我相信它与 COM 的工作方式有关。在我的情况下,我需要 StartMonitoring 来启动一个后台线程,当 StopMonitoring 被调用时,它会发出这个后台线程退出的信号,然后等待它退出。现在因为线程没有启动但已经给出了一个有效的句柄,StopMonitoring 将发出信号并永远等待。如果我绕过Wait强行结束StopMonitoring,那么MonitorThreadProc就会执行,完全不在sink
  • 当您期望MonitorThreadProc 启动但它没有启动时,我认为您可以使用调试器并检查线程。也许那里的某些东西表明究竟是什么被锁定并阻止新线程启动。
  • 如果 COM 服务器在加载时调用它(即从它的 DllMain),线程创建将失败。
  • @RomanR. 线程刚刚创建,仅此而已,调用堆栈仅显示 ntdll.dll!78d820c 类型的框架。它只有在 FinalRelease 完成后才开始工作,这对我来说毫无意义

标签: c++ windows multithreading atl


【解决方案1】:

奇怪的行为是由于在 DLL 加载期间持有的加载程序锁。在保持加载程序锁之前,线程永远不会被调度,因此我没有看到代码执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多