2011-12-01 47 views
2

有一系列互斥體。 我的功能:如何等待,直到互斥鎖解鎖?

  1. 檢查是互斥被鎖定

2A。如果不是,則鎖定它

2b。如果鎖定,等待解鎖並鎖定它

另一個功能將其解鎖。

的問題是,我在等待部碰撞:

HANDLE mutexes[N]; 

void func(int i) 
{ 
    // (*) wait until unlocked or create if unlocked 
    while ((mutexes[i] = CreateMutex(NULL, TRUE/*same with FALSE*/, NULL)) != NULL); 
    /*or WaitForSingleObject(mutexes[i], INFINITE)*/ 

    mutexes[i] = CreateMutex(NULL, TRUE, NULL); 
} 

在(*)指出我有崩潰 - 訪問衝突。當它試圖創建先前已經創建的互斥體[i]時發生崩潰。我不能使用WaitForSingleObject,因爲第一次沒有創建mutexes [i],文檔說WaitForSingleObject是未定義的。此外,如果我使用這個功能,我會得到同樣的崩潰。

所有我需要的就是這樣簡單的僞代碼的模擬

if (mutex_has_been_created[mutexes[i]]) 
    WaitUntilRelease() 
CreateMutex(); 

我試圖把它包在一個關鍵的部分,得到了相同的結果。我確信i在正確的範圍內。 我不能使用Boost/pThreads/etc。

我知道我的問題很容易,但我找不到解決方案。在我見過的所有例子中,在WaitForSingleObject之前創建了一個互斥鎖,這對我不起作用。

謝謝。

回答

13

您確實需要理清代碼的邏輯:互斥鎖的創建和鎖定/解鎖是不同的操作,應該這樣處理。坦率地說,「試圖創建已經創建的互斥體」的所有這些業務並沒有太多意義。

簡言之:

  1. CreateMutex初始化( 「創建」)的互斥。
  2. WaitForSingleObject等人鎖定互斥鎖(或超時)。
  3. ReleaseMutex解鎖它。
  4. CloseHandle破壞它。

您可以根據需要多次創建/銷燬互斥鎖​​。

當您嘗試鎖定已被其他人鎖定的互斥鎖時,您的線程將自動阻塞,直到互斥鎖變爲可用。

+0

我認爲CreateMutex意味着鎖定它。我還沒有找到「LockMutex」函數什麼的。 – fogbit

+1

@fogbit:不,CreateMutex初始化互斥鎖。 WaitForSingleObject鎖定它。看到我更新的答案。 – NPE

1

使用posix線程可能會使用condition variables;我不知道WinAPI是否提供類似的東西。

4

如果你想等到它被解鎖,只有鎖定它,那麼你可以鎖定它。這正是您這樣做時發生的情況。當您嘗試鎖定代碼塊時,直到互斥鎖變爲可用,然後將其鎖定。

+0

我不知道如何鎖定它。我認爲「創造互斥體」意味着「鎖定」它。如果沒有,我怎樣才能鎖定它在winapi? – fogbit

+2

這就是'WaitForSingleObject'的作用。 –

1
HANDLE mutexes[N] 

void InitMutexes(int N) 
{ 
    for (int i =0; i < N ; i++) 
    {   
     mutexes[i] = CreateMutex(NULL, FALSE, NULL); 
    } 
} 
void WaitForMutex(int n) 
{ 
    WaitForSingleObject(mutexes[n], INFINITE); 
} 
void ReleaseMutex(int n) 
{ 
    ReleaseMutex(mutexes[n]); 
} 
void CleanUpMutexes(int N) 
{ 
    for (int i=0; i < N; i++) 
    { 
      ReleaseMutex(mutexes[i]); CloseHandle(mutexes[i]); 
    } 
} 

希望有所幫助。