c++ - 为什么没有获取互斥体?

标签 c++ multithreading winapi mutex

我一直在研究 WinAPI 中可用的所有不同同步原语,但一直在努力解决本应简单的事情。为什么下面的代码不起作用?

class MultiThreadedCounter
{
private:
    int count; HANDLE hMutex;

public:
    void IncrementCounter()
    {
        if (count == 0)
            hMutex = CreateMutex(NULL, TRUE, NULL);
        count++;
    }

    void DecrementCounter()
    {
        count--;
        if (count == 0)
            ReleaseMutex(hMutex);
    }

    void WaitForCounterToReachZero()
    {
        WaitForSingleObject(hMutex, INFINITE);
        CloseHandle(hMutex);
    }
};
MultiThreadedCounter extractionsInProgressCounter;

它绝对是按正确的顺序调用的。首先,主线程在异步任务之前调用 IncrementCounter()(此处为线程 sleep )。然后主线程调用WaitForCounterToReachZero()。最后,后台线程在完成其工作后调用 DecrementCounter(),这应该允许主线程继续进行。

但是,WaitForSingleObject 并未等待。它立即返回,并带有 WAIT_OBJECT_0。它为什么要这么做?这几乎就像最初从未获得互斥体一样。但是,在对CreateMutex的调用中,我将bInitialOwner设置为TRUE,这就是为什么我不明白为什么它似乎不已被获得。我想我误解了一些东西。

谢谢。

编辑1:

好的,为了测试,我将 IncrementCounter() 更改为:

void IncrementCounter()
{
    if (count == 0)
    {
        hMutex = CreateMutex(NULL, TRUE, NULL);
        DWORD var1 = WaitForSingleObject(hMutex, INFINITE);
        DWORD var2 = WaitForSingleObject(hMutex, INFINITE);
    }
    count++;
}

这真的真的应该让它陷入僵局,但是没有,对 WaitForSingleObject 的两次调用都立即返回,var1var2 都等于 0 (根据 header ,它是 WAIT_OBJECT_0)。

CreateMutex 的调用无法正常工作,不是吗?然而,hMutex 被设置为一个合理的值,而 GetLastError() 仍为 0。太困惑了...

编辑2:谢谢大家的帮助。我从来没有让它发挥作用,但是,我现在意识到无论如何我都以错误的方式这样做。因此,我将所有内容都切换到一个事件,此时它起作用了,然后添加了一些条件来处理无序增量和减量,然后添加了一个关键部分来保护计数变量。它有效:)

class MultiThreadedCounter
{
private:
int count; HANDLE hEvent; CRITICAL_SECTION criticalSection;

public:
void IncrementCounter()
{
    EnterCriticalSection(&criticalSection);
    if (count == 0)
        ResetEvent(hEvent);
    count++;
    LeaveCriticalSection(&criticalSection);
}

void DecrementCounter()
{
    EnterCriticalSection(&criticalSection);
    if (count > 0)
        count--;
    if (count == 0)
        SetEvent(hEvent);
    LeaveCriticalSection(&criticalSection);
}

void WaitForCounterToReachZero()
{
    WaitForSingleObject(hEvent, INFINITE);
}

MultiThreadedCounter()
{
    hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
    InitializeCriticalSection(&criticalSection);
    count = 0;
}

~MultiThreadedCounter()
{
    CloseHandle(hEvent);
    DeleteCriticalSection(&criticalSection);
}
};

最佳答案

您没有显示MultiThreadedCounter的构造函数。如果没有这个,就没有地方将 count 初始化为 0,这意味着第一次调用 IncrementCounter 几乎肯定不会调用 CreateMutex

你的构造函数应该类似于

MultiThreadedCounter()
    : count(0)
    , hMutex(NULL)
{
}

顺便说一句,如果您需要在单个进程中的线程之间使用的锁,您可以考虑使用 critical section相反。

关于c++ - 为什么没有获取互斥体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18183288/

相关文章:

c++ - 常量 int = int 常量?

c++ - 如何从 unordered_set 中获取单个项目?

multithreading - 什么是跳线,什么时候需要?

c++ - GetDiBits:BITMAPINFOHEADER 中传递的不同维度

c++ - OpenSL ES 中是否有等效于 OpenAL <alc.h> 的内容?

c++ - 运行时绑定(bind)和虚拟继承

java - 当线程进入 Java 中的同步块(synchronized block)/方法时到底发生了什么

multithreading - 使用依赖注入(inject)时如何使共享资源线程安全?

windows - 什么是Windows "USER objects"

c++ - Windows 7 是否使用 GDI 或新的 DWM/WDDM 呈现旧程序的控件?