2011-09-26 121 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; 
}