【问题标题】:WaitForSingleObject not workWaitForSingleObject 不起作用
【发布时间】:2010-08-24 01:22:50
【问题描述】:

请看下面的代码:

#include <windows.h>
int main(int argc, char* argv[])
{
    HANDLE _mutex = ::CreateMutex(NULL, FALSE, "abc");
    if (!_mutex)
        throw std::runtime_error("CreateMutex failed");

    if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

    printf("Must lock here\n");

    if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

    printf("Why come here????\n");
    return 0;
}

我不知道为什么控制台打印出来:

Must lock here
Why come here???

互斥锁不起作用吗?我只想显示结果

Must lock here

并在打印上面的文字后阻塞。

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    除了你的主线程之外,没有其他线程拥有互斥锁的所有权。这就是它没有阻塞并且您会看到两个打印语句的原因。以下是 MSDN 链接的摘录,其中清楚地解释了how mutex works

    在一个线程获得一个线程的所有权之后 mutex,可以指定同一个mutex 在多次致电 等待功能而不阻塞其 执行。这可以防止线程 在等待一个 它已经拥有的互斥锁。释放 在这种情况下它的所有权 情况下,线程必须调用 每次释放互斥锁一次 互斥体满足条件 等待函数。

    您可以创建多个线程来查看实际的阻塞行为。注意:您的代码也缺少ReleaseMutex 调用。

    【讨论】:

      【解决方案2】:

      如果您想要一个行为与您描述的一样的同步原语,您可以使用自动重置事件。

       #include <windows.h>
       #include <stdexcept>
       #include <stdio.h>
       int main(int argc, char* argv[])
       {
           HANDLE _mutex = ::CreateEvent(NULL, FALSE,         TRUE, NULL);
                                               // auto reset  // initially signalled
           if (!_mutex)
               throw std::runtime_error("CreateEvent failed");
      
           if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0) 
               throw std::runtime_error("WaitForSingleObject failed");
           // unsignalled now
      
           printf("Must lock here\n");
      
           // will block forever until someone calls SetEvent
           if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
               throw std::runtime_error("WaitForSingleObject failed");
      
           printf("Why come here????\n");
           return 0;
       }
      

      【讨论】:

      • 我知道 Mutex 是如何工作的。你的答案是正确的。谢谢你:)
      【解决方案3】:

      更新:阅读 c++ 中的互斥锁

      我不是 C++ 专家,但线程拥有互斥锁。在您的示例中,同一线程打开/创建命名互斥锁,因此第二次调用不会阻塞。

      看看这个:“使用互斥对象。”

      http://msdn.microsoft.com/en-us/library/ms686927(v=VS.85).aspx

      -奥辛

      【讨论】:

        【解决方案4】:

        它不“工作”的“原因”是没有理由应该这样做。 FALSE 参数表示您正在寻找一个现有的互斥锁,一方面。阅读文档。 http://msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx

        您确定要使用互斥锁而不是 CRITICAL_SECTION?

        【讨论】:

        • 第二个参数不是这个意思。 “如果此值为 TRUE 并且调用者创建了互斥体,则调用线程获得互斥体对象的初始所有权。否则,调用线程不会获得互斥体的所有权。要确定调用者是否创建了互斥体,请参阅返回值部分。”传递 false 只是意味着创建的互斥锁在创建时不属于当前线程。
        猜你喜欢
        • 1970-01-01
        • 2021-09-03
        • 2016-06-20
        • 1970-01-01
        • 1970-01-01
        • 2010-12-30
        • 1970-01-01
        • 2011-04-18
        相关资源
        最近更新 更多