我一直在研究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:
OK,所以测试,我改变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);
}
};
我对winapi了解不多,但是在调用IncrementCounter之前调用WaitForSingleObject会发生什么? hMutex将处于什么状态,并且该功能是否能够应对? – PlasmaHH
你能向我们展示你在哪些线程之间共享对象的代码吗?你确定吗,他们访问同一个对象而不是两个不同的对象? – ogni42
@ ogni42:我会尽量在一分钟内将其编辑成问题,但是,我非常肯定他们肯定是同一个对象。 'MultiThreadedCounter extractionsInProgressCounter;'在任何函数之外,并且所有的函数都使用'extractionsInProgressCounter',它不会在任何地方重新定义。我几乎可以确定它是同一个对象,因为当调用WaitForSingleObject时,count被设置为1,hMutex被设置为最近运行的0xE8。所以初始化一定很合理。 – niemiro