《Win32多线程程序设计》学习笔记 第4章 同步控制之Mutex互斥器
Win32的Mutex和Critical Seciton非常类似。但是他以牺牲速度来增加弹性。Mutex是核心对象
Mutex 和Critical Section 的区别:
- 锁住一个未被拥有的Mutex,比锁住一个未被拥有的Critical Section需要花费几乎100倍的时间 。
- Mutex可以跨进程使用。 Critical Section只能在一个进程中使用。
- 等待一个Mutex,你可以指定“结束等待” 的时间长短。对于critical section 就不行。
两种对象的相关函数比较:
CRITICAL_SECTION Mutex核心对象
InitializeCriticalSection() CreateMutex(), OpenMutex()
EnterCriticalSection() WaitForSingleObject(), WaitForMultipleObject(), MsgWaitForMultipleObject()
LeaveCriticalSection() ReleaseMutex()
DeleteCriticalSection() CloseHandle()
为了能跨进程使用mutex,应该在产生mutex时指定名称。那么系统的其他进程就可以使用名称来处理这个mutex。
基本知识:
产生一个互斥器
HANDLE WINAPI CreateMutex(
__in LPSECURITY_ATTRIBUTES lpMutexAttributes, //安全属性,NULL表默认
__in BOOL bInitialOwner, //如果你希望“调用CreateMutex”的这个线程拥有产生出来的mutex,就将此值设为TRUE。
__in LPCTSTR lpName //mutex名称
);
返回值:如果成功,返回一个handle,否则返回NULL,调用GetLastError获取进一步的信息。如果指定的mutex名称已存在,GetLastError()会传回ERROR_ALREADY_EXISTS.
当不需要mutex时,调用CloseHandle关闭它。
打开一个互斥器(mutex)
任何进程和线程都可以根据名称打开一个已经存在的mutex。
如果 你调用createmutex并指定了一个已经存在的mutex名称。win32会返回给你一个mutex的handle。而不会产生一个mutex,getlasterror回传会 ERROR_ALREADY_EXISTS
锁住一个互斥器(mutex)
要获取mutex的拥有权,使用wait..。系列函数。wait。。()对mutex所作的事情类似于enterCriticalSection对CriticalSection做的事情。一旦没有任何线程拥有mutex,它就处于激发状态,wait...就会成功。
释放一个互斥器(mutex)
获得mutex的线程调用ReleaseMutex,将之释放,使mutex处于激发状态。
BOOL WINAPI ReleaseMutex(
__in HANDLE hMutex //欲释放之mutex的handle
);
返回值:成功TRUE,失败FALSE
处理被舍弃的互斥器(Mutex)
如果线程拥有一个mutex而在结束前没有调用ReleaseMutex,mutex不会被摧毁,其会被视为“未被拥有”以及“未被激发”,而下一个等待中的线程会被以WAIT_ABANDONED_0通知,不论线程是应为ExitThread而结束,或是当掉而结束。
如果其他线程正以WaitForMultipleObjects()等待此mutex,该函数也会返回,传回值介于 WAIT_ABANDONED_0和WAIT_ABANDONED_0_n+1之间,其中n指handle数组的元素个数。线程可以以此来了解那个mutex被放弃了。至于WaitForSingleOBject,只返回WAIT_ABANDONED_0
为什么有一个最初的拥有者
CreateMutex的第二个参数允许你指定现行线程是否立刻拥有即将产生的mutex,他是为了阻止race condition的发生。