我一直在研究 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
立即返回var1
并且var2
都等于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);
}
};