2011-09-26 120 views
1

我正試圖在多線程程序上實現相互交換。我不知道我是否做得對,而且很難測試。我是否正確實施了Mutal Exchange?

main.cpp中,我有這樣的事情:

//mutex handle 
HANDLE hIOMutex = CreateMutex (NULL,FALSE,NULL); 

//main 
while (1) { 
    Sleep(STEP); 

    WaitForSingleObject(hIOMutex,INFINITE); 

    //DO STUFF 

    ReleaseMutex(hIOMutex); 
} 
return 0; 

而且在功能使用的其他線程

void Case::account_login(Connection* Con) { 
    //mutex handle 
    HANDLE hIOMutex = CreateMutex (NULL,FALSE,NULL); 

    WaitForSingleObject(hIOMutex,INFINITE); 

    //DO STUFF 

    ReleaseMutex(hIOMutex); 
    return; 
} 

這是正確的嗎?部分代碼甚至使用相同的HANDLE,還是我在本地聲明它們,從而搞砸了功能?

如果我錯過了任何重要信息,請告訴我。

謝謝。

回答

0

是代碼段甚至使用相同的手柄還是我宣佈他們在本地,因此搞砸了的功能?

不,他們沒有使用相同的句柄或相同的互斥體(對於同一個互斥體可能有多個句柄)。在發佈的代碼中,兩個線程各自擁有自己的互斥鎖,這意味着訪問由這兩個互斥鎖保護的公共數據將不會「互斥」。

你的選擇都或多或少:

  1. 通過互斥體作爲參數傳遞給線程函數
  2. 定義互斥處理作爲Connection結構/類
  3. 的成員使用命名的互斥體(在一側創建命名互斥體並在另一側打開命名互斥體)
  4. 使句柄成爲全局變量。

編輯:我把「使處理全局變量」最後一個很好的理由:它是該組中最糟糕的選擇。然而,由於OP堅持一個例子...

// globals.h 
#include <windows.h> 
extern HANDLE hIOMutex; 

// globals.cpp 
#include "globals.h" 
HANDLE hIOMutex = INVALID_HANDLE_VALUE; 

// main.cpp 
#include "globals.h" 
int main() 
{ 
    // initialize global variables. 
    hIOMutex = CreateMutex (NULL,FALSE,NULL); 
    // main code. 
    while (1) { 
     Sleep(STEP); 
     WaitForSingleObject(hIOMutex,INFINITE); 
     //DO STUFF 
     ReleaseMutex(hIOMutex); 
    } 
} 

// case.cpp 
#include "case.h" 
#include "globals.h" 
void Case::account_login(Connection* Con) 
{ 
    WaitForSingleObject(hIOMutex,INFINITE); 
    //DO STUFF 
    ReleaseMutex(hIOMutex); 
} 
+0

你能否提供瞭如何使手柄全球的代碼?當我試圖聲明它是'extern'時,它會拋出錯誤。 – Matthew

+0

@Matthew:你應該真的考慮其他的選擇。我把「使句柄成爲一個全局變量是有原因的:這是最糟糕的解決方案(從軟件工程的角度來看)」,提供了一個示例。 –

+0

謝謝。似乎有效!我會記住將互斥量作爲參數傳遞給未來,因爲我改進了代碼。 – Matthew

0

我會用一個命名的互斥體,特別是如果在使用互斥的兩個地方都在不同的地方。但是,請確保您創建一個Mutex_Name地方,避免錯字錯

LPCTSTR lpMutex_Name = <name>; 

//mutex handle 
HANDLE hIOMutex = CreateMutex (NULL,FALSE,lpMutex_Name); 

//main 
while (1) { 
    Sleep(STEP); 

    WaitForSingleObject(hIOMutex,INFINITE); 

    //DO STUFF 

    ReleaseMutex(hIOMutex); 
} 
return 0; 
And in a function used by the other thread: 

void Case::account_login(Connection* Con) { 
    //mutex handle 
    HANDLE hIOMutex = CreateMutex (NULL,FALSE, lpMutex_Name); 

    WaitForSingleObject(hIOMutex,INFINITE); 

    //DO STUFF 

    ReleaseMutex(hIOMutex); 
    return; 
}