我一直在研究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