【问题标题】:Replacing WaitForMultipleObjects in Qt在 Qt 中替换 WaitForMultipleObjects
【发布时间】:2012-09-09 03:27:34
【问题描述】:

我不熟悉 WINAPI,我正在寻找一种方法来替换在一个示例中使用的 WaitForMultipleObjects,我只使用 Qt 将任何东西移植到 Qt。有可能吗?

编辑:(根据 cmets 的要求提供更多信息)

第 3 方 API 提供一系列事件:

HANDLE  m_hEv[MAX_EV];

在一个线程的 endles-loop 中,程序等待这样的事件:

WaitForMultipleObjects(m_EvMax, m_hEv, FALSE ,INFINITE )

HANDLE 类型似乎是 void*。 所以我想知道,是否有任何 Qt 类可以观察 m_hEv 的变化并解锁线程执行。

【问题讨论】:

  • 你能提供更多关于 Winapi 的 WaitForMultipleObjects 做什么的上下文吗?我知道 Qt 但不知道 winapi
  • 您在程序中使用WaitForMultipleObject 到底是为了什么?
  • @jdi:它允许您等待组中的所有或任何事件发生(例如等待一组线程完成)。

标签: qt winapi porting


【解决方案1】:

WaitForMultipleObjects 是一种通用函数,适用于许多事物:线程、进程、互斥体等。Qt 是一个 OOP 库,其中每个类都公开了它支持的操作。因此,Qt 中的等效操作取决于您使用的类。例如,对于线程,使用 QThread::wait。对于互斥体,使用 QMutex::lock。

【讨论】:

    【解决方案2】:

    没有将WaitForMultipleObjects 移植到 WinAPI 之外的简单方法。 WinAPI 有一个“优势”,即所有可锁定资源(套接字、文件、进程)都提供相同的通用非类型安全HANDLE,即您的void*。与根据资源类型具有不同锁定和信号方式的其他平台不同,WinAPI 中的事件处理在很大程度上独立于资源。然后可以存在像WaitForMultipleObjects 这样的通用函数,它不需要关心是谁产生了句柄。因此,您必须了解代码试图做什么,并根据场景以不同的方式模仿它。

    最大的区别在于WaitForMultipleObjects 第三个参数,在您的情况下为 FALSE。这意味着一旦等待数组的任何单个事件发生,它就会退出等待。这是更简单的方案,可以用QWaitCondition 替换。

    1. 您将把QWaitCondition* 传递到发出事件信号的代码中,而不是m_hEv(很可能通过WinAPI SetEvent(m_hEv[x]))
    2. 不要使用 WaitForMultipleObjects,而是使用 QWaitCondition::wait()。
    3. 不要使用SetEvent(),而是使用QWaitCondition::wakeOne()。

    如果第三个参数为 TRUE,那么 WinAPI 代码会一直等待,直到所有 m_hEv 事件都发出信号。此类功能的既定名称是同步屏障,它也可以用QEventCondition 模拟,但不是从Qt 框架中出来的。我从来不需要自己做任何事情,但是 SO 有一些想法:

    Qt synchronization barrier?

    【讨论】:

    • 非常感谢您对 WaitFor...Object 工作原理的精彩解释。我无法理解,如何将 void* 评估为线程锁。然而我已经明白了。我已经订购了 Qt (qt-project.org/doc/qt-4.8/threads.html#recommended-reading) 推荐的所有书籍。似乎,在某些情况下,对底层平台的理解是不可避免的。关于我的意图,似乎只有引入一个附加层并在特定于平台的代码中等待 Linux 和 Win 上的事件。
    • 恕我直言,您不需要 Linux 特定的不可移植代码。 Qt 在线程哲学上与 Linux 非常接近,因此不应该存在像 WinAPI 那样严重的移植问题。一旦你完成了你的 WinAPI 平台特定代码,我敢打赌它的界面看起来会很像 QWaitCondition :)
    • 我不明白如何在 QWaitCondition 中等待多个 QMutex 对象,等待函数似乎只接受一个互斥锁。有没有办法让它接受多个 QMutex'es?
    • @Stormenet:如果您希望 QWaitCondition 从一次调用中接受多个 QMutex,那么您希望它做什么?你不能多次持有一个线程——你会遇到死锁。等待函数肯定只接受一个 QMutex。您应该使用不同的 QMutex 实例从任意数量的线程中调用它。这就是等待条件的全部意义所在。
    • 我想我现在明白如何使用它了。无需等待多个对象(事件),例如 ProducerItemsAvailable 和 ThreadStopRequest,您只需等待一个 QWaitCondition 并触发它,同时跟踪触发 wakeOne 的原因并采取正确的操作。这是对的吗?
    猜你喜欢
    • 2014-02-23
    • 1970-01-01
    • 2021-12-11
    • 2016-05-24
    • 1970-01-01
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多