window下线程同步之(Mutex(互斥器) )
使用方法:
1、创建一个互斥器:CreateMutex;
2、打开一个已经存在的互斥器:OpenMutex;
3、获得互斥器的拥有权:WaitForSingleObject、WaitForMultipleObjects 等一类等待的函数……(可能造成阻塞);
4、释放互斥器的拥有权:ReleaseMutex;
5、关闭互斥器:CloseHandle;
函数原型:
HANDLE WINAPI CreateMutex( __in_opt LPSECURITY_ATTRIBUTES lpMutexAttributes, __in BOOL bInitialOwner, __in_opt LPCTSTR lpName );
lpMutexAttributes : 第一个参数表示安全控制,一般直接传入NULL。 bInitialOwner第二个参数用来确定互斥量的初始拥有者。 如果传入TRUE表示互斥量对象内部会记录创建它的线程的线程ID号并将递归计数设置为1,由于该线程ID非零,所以互斥量处于未触发状态,表示互斥量为创建线程拥有。 如果传入FALSE,那么互斥量对象内部的线程ID号将设置为NULL,递归计数设置为0,这意味互斥量不为任何线程占用,处于触发状态。 lpName第三个参数用来设置互斥量的名称,在多个进程中的线程就是通过名称来确保它们访问的是同一个互斥量。
※ 命名标准:Mutex 可以跨进程使用,所以其名称对整个系统而言是全局的,所以命名不要过于普通,类似:Mutex、Object 等。
最好想一些独一无二的名字等!
固有特点(优点+缺点):
1、是一个系统核心对象,所以有安全描述指针,用完了要 CloseHandle 关闭句柄,这些是内核对象的共同特征;
2、因为是核心对象,所以执行速度会比 Critical Sections 慢几乎100倍的时间(当然只是相比较而言);
3、因为是核心对象,而且可以命名,所以可以跨进程使用;
4、Mutex 使用正确的情况下不会发生死锁;
5、在“等待”一个 Mutex 的时候,可以指定“结束等待”的时间长度;
6、可以检测到当前拥有互斥器所有权的线程是否已经退出!Wait……函数会返回:WAIT_ABANDONED
#include <iostream> #include <windows.h> using namespace std; HANDLE g_hMutex = NULL; const int g_Number = 3; DWORD WINAPI ThreadProc1(__in LPVOID lpParameter); DWORD WINAPI ThreadProc2(__in LPVOID lpParameter); DWORD WINAPI ThreadProc3(__in LPVOID lpParameter); int main() { g_hMutex = CreateMutex(NULL,FALSE,NULL); //TRUE代表主线程拥有互斥对象 但是主线程没有释放该对象 互斥对象谁拥有 谁释放 // FLASE代表当前没有线程拥有这个互斥对象
HANDLE hThread[ g_Number ] = {0}; int first = 1, second = 2, third = 3; hThread[ 0 ] = CreateThread(NULL,0,ThreadProc1,(LPVOID)first,0,NULL); hThread[ 1 ] = CreateThread(NULL,0,ThreadProc2,(LPVOID)second,0,NULL); hThread[ 2 ] = CreateThread(NULL,0,ThreadProc3,(LPVOID)third,0,NULL); WaitForMultipleObjects(g_Number,hThread,TRUE,INFINITE); CloseHandle( hThread[0] ); CloseHandle( hThread[1] ); CloseHandle( hThread[2] ); CloseHandle( g_hMutex ); return 0; } DWORD WINAPI ThreadProc1(__in LPVOID lpParameter) { WaitForSingleObject(g_hMutex, INFINITE);//等待互斥量 cout<<(int)lpParameter<<endl; ReleaseMutex(g_hMutex);//释放互斥量 return 0; } DWORD WINAPI ThreadProc2(__in LPVOID lpParameter) { WaitForSingleObject(g_hMutex, INFINITE);//等待互斥量 cout<<(int )lpParameter<<endl; ReleaseMutex(g_hMutex);//释放互斥量 return 0; } DWORD WINAPI ThreadProc3(__in LPVOID lpParameter) { WaitForSingleObject( g_hMutex, INFINITE);//等待互斥量 cout<<(int)lpParameter<<endl; ReleaseMutex(g_hMutex);//释放互斥量 return 0; }