首页 > 解决方案 > 什么 C++ 相当于 winapi 的 MsgWaitForMultipleObjectsEx

问题描述

我正在从使用本机 Win32 API 调用来管理线程的消息队列过渡到使用我自己的 C++ 代码。我遇到了一个我无法完全回答的问题。

给定以下代码片段

LRESULT QueueConsumeThread()
{
    MSG msg = { 0 };

    HANDLE hHandles[] = { hHandle1, hHandle2 };
    while (true)
    {
        DWORD dwRes;
        switch (dwRes = ::MsgWaitForMultipleObjects(_countof(hHandles), hHandles, FALSE, INFINITE, QS_ALLEVENTS))
        {
            case WAIT_OBJECT_0 :
                DoSomething();
                break;
            case WAIT_OBJECT_0 + 1:
                DoSomething2();
                break;
            case WAIT_OBJECT_0 + _countof(hHandles):
                ATLASSERT(msg.message == WM_QUIT);
                return 1;
        }
    }

    return 1;
}

我在许多资料中都读到,一个特定的线程应该与一个关联condition_variable,而且使用多个condition_variables 或调用wait_for()wait_until()听起来效率不高。

以下来源建议实施safe_queueusing condition_variables。我猜这PeekMessage/GetMessage/MsgWaitForMultipleObject工作类似,但是队列的每个单元应该持有什么样的数据并能够接收事件信号?

编辑:我问这个是因为我必须编写一个跨平台的应用程序。

标签: c++multithreadingc++11winapi

解决方案


与窗口同步事件(可以处于signalled状态)相反,它与状态std::condition_variable解耦。因此,最自然的方法是定义几个条件并使用单个等待/报告它们condition_variable

std::unique_lock<std::mutex> lock(m);
cv.wait(lock, []{ return ready1 || ready2 || ready3; });
if (ready1) { ... }
if (ready2) { ... }
if (ready3) { ... }

std::unique_lock<std::mutex> lock(m);
ready1 = true;
cv.notify_one();

推荐阅读