【问题标题】:WaitForMultipleObjects with a mutex and an event带有互斥锁和事件的 WaitForMultipleObjects
【发布时间】:2012-09-06 07:30:55
【问题描述】:

如果我有以下 C++ 代码(适用于 Windows 操作系统):

HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE hMutex = ::CreateMutex(NULL, FALSE, NULL);

HANDLE hHandles[] = {
    hEvent,
    hMutex
};

DWORD dwR = ::WaitForMultipleObjects(2, hHandles, FALSE, INFINITE) - WAIT_OBJECT_0;

//if dwR == 0, what state is hMutex in?
//Or, do I need to call ReleaseMutex(hMutex) in that case?

我不确定如何处理有关互斥锁的这种情况。

【问题讨论】:

    标签: c++ winapi synchronization mutex


    【解决方案1】:

    dwR 不是完全为零,它是WAIT_OBJECT_0 + 0,即您对第一个提供的句柄的等待得到了满足。这是事件的句柄,所以你不需要触摸你的互斥体。

    如果结果是WAIT_OBJECT_0 + 1,那么它是用于成功等待的互斥句柄。一旦你完成了你需要做的事情,你可以通过调用ReleaseMutex来释放所有权。

    【讨论】:

    • 谢谢。这就是我需要知道的。顺便说一句,说到WAIT_OBJECT_0,我在检查之前减去了它。
    • 哦,是的,你做到了 - 抱歉我错过了那部分。
    • 不要像你一样无条件地减去它。 WaitForMultipleObject() 可以返回不应从 WAIT_OBJECT_0 中提取的其他错误代码。仅当WaitForMultipleObjects() 返回WAIT_OBJECT_0 + 0WAIT_OBJECT_0 + 1 时减去它,仅此而已。
    【解决方案2】:

    该函数用作互斥体上的 WaitForSingleObject 方法。 MSDN (MSDN Example) 中有一个示例,说明了使用 WaitForSingleObject 获取互斥锁。 WaitForMultipleObjects 在使用 Mutex 时具有相同的行为。

    【讨论】:

    • 好的,谢谢。单个对象很容易。我在这里主要关心的是当事件发出信号并且互斥锁挂起时不要创建“竞争条件”,可以这么说......但是上面的@RomanR确认我只需要在 WaitForMultipleObjects 返回它的索引时释放互斥锁。
    【解决方案3】:

    这是一个很好的问题。无论如何,Microsoft 文档对此并不十分清楚。

    带有 bWaitAll = FALSE 的 WaitForMultipleObjects 的文档说:“如果多个对象发出信号,则函数返回数组中第一个句柄的索引,其对象发出信号。”

    但是文档还说“仅对信号状态导致函数返回的一个或多个对象进行修改”,这是有道理的,因为否则我们将不知道是否还会获取 Mutex。

    根据我的实验,WaitForMultipleObjects 不会获取“额外的”互斥锁,这很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-23
      • 2013-03-30
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      • 2019-01-15
      相关资源
      最近更新 更多