为什么不获取互斥锁?

时间:2013-08-12 09:11:14

标签: 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()。然后主线程调用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(根据标题是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);
}
};

1 个答案:

答案 0 :(得分:2)

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

您的构造函数应该类似于

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

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