等效于C++ 11线程中的WAIT_ABANDONED

typ*_*232 3 c++ winapi multithreading c++11

我正在重写使用WinAPI进行线程化以使用新标准线程库的代码.

我想知道在C++ 11中注意到互斥体被遗弃或丢失的等效方式.

以下代码必须将初始化过程"外包"到创建的线程,但是在完成之前不应该返回并且知道初始化的结果.

bool Foo::Example()
{
    m_thread = std::thread(&Foo::ThreadProc, this);

    // wait for event before waiting for mutex
    WaitForSingleObject(m_hEvent, INFINITE);
    ResetEvent(m_hEvent);

    // the thread aquired the mutex. now wait until it is released or abandoned
    DWORD ret = WaitForSingleObject(m_hMutex, INFINITE);
    ReleaseMutex(m_hMutex);

    // check the result
    if (ret == WAIT_ABANDONED)
        return false;
    return true;
}
void Foo::ThreadProc()
{
    // aquire mutex and signal that it's done
    WaitForSingleObject(m_hMutex, INFINITE);
    SetEvent(m_hEvent);

    // ... initialization (required to be in this thread)

    if (initializationfailure)
        return; // failure. mutex is abandoned

    // success. mutex is unlocked
    ReleaseMutex(m_hMutex);

    // ... do the work
}
Run Code Online (Sandbox Code Playgroud)

什么是WAIT_ABANDONED支票的替代品?我在std :: mutex中找不到任何东西.它甚至说The behavior is undefined if the mutex is not unlocked before being destroyed, i.e. some thread still owns it.没有相应的东西?std线程库中的任何东西都接近这个?

我还提出了改进代码的建议.这样一个简单的任务似乎太过同步了.

Jon*_*ely 7

没有等价物.您可以使用RAII来解锁互斥锁并避免首先放弃互斥锁,然后您就不需要能够对其进行测试.

您可以使用future而不是等待事件并使用互斥锁,这使得它比容易出错的显式同步更简单:

bool Foo::Example()
{
    std::promise<bool> p;
    auto res = p.get_future();
    m_thread = std::thread(&Foo::ThreadProc, this, std::ref(p));
    return res.get();
}
void Foo::ThreadProc(std::promise<bool>& p)
{
    // ... initialization (required to be in this thread)

    if (initializationfailure)
    {
        p.set_value(false); // failure.
        return;
    }

    p.set_value(true);

    // IMPORTANT: p is a dangling reference now!

    // ... do the work
}
Run Code Online (Sandbox Code Playgroud)

主线程将阻塞,直到履行完成,然后根据初始化是否有效返回true或false.

您可以通过制作它来避免悬空引用ThreadProc(std::promise<bool> p),然后将其传递给std::move(p)而不是,std::ref(p)但我认为std::threadVisual C++中不支持完全转发仅移动类型.

  • @ typ1232:如果你需要表示成功或失败,只需使用一个额外的变量即可.你应该*不要*使用被遗弃而不是放弃来传达程序状态.`WAIT_ABANDONED`状态是"哦废话,有些可怕,*可怕*错误,现在最好尽快拯救"标志,不是正常程序操作期间应该发生的事情. (5认同)
  • @ typ1232,我添加了一个比依赖废弃的互斥体简单得多的替代方案 (2认同)