C++互斥器:Mutex

互斥器的功能是,使多个线程和谐工作。同一时间内,只能有一个线程得到互斥对象,并获得资源操作权限,那么如果同一时间其他线程也想去操作资源,此时就会因为Mutex未处于激发状态,而无奈的等待…这时候,线程就会进入blocking(阻塞)状态,直到Mutex让出来。

总结下Mutex的操作步骤,分为以下几个功能:

1. 产生一个全局互斥器Mutex(一个Mutex可以看做一个资源,如果要多个资源,则需要创建多个Mutex句柄);

2. 锁住互斥器Mutex:获得一个Mutex的拥有权,其他线程只能等待。当需要锁操作时,如果此时锁未处于激活状态,线程就得等待(也就是阻塞状态/sleep)并每隔一段时间尝试着再次去占用Mutex,不行就继续阻塞直到Mutex被让出;

3. 释放互斥器Mutex,使得后一个等待的线程能够拥有它并得以获得资源;

 

这里需要说明的是,Mutex的拥有权并非属于那个产生它的线程,而是最后那个获得它且未释放的线程。线程拥有了Mutex就好像线程进入了临界区域一样。一次只能有一个线程获得Mutex。

和大部分核心对象一样,Mutex是通过计数来实现互斥,当Mutex被占用时计数为1,当Mutex未被占用时计数降低为0;

但是,有些情况是残酷的所以必须避免:在一个程序中,线程绝对不应该在即将结束时还拥有一个Mutex,否则该Mutex将无法被释放。

 

Win32下Mutex相关接口:

1. 创建一个互斥器,该接口返回一个HANDLE:

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName);

2. 打开一个互斥器,该互斥器已被创建过:

HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName);

3. 等待一个资源对象:

DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);

--hHandle:mutex句柄

--dwMilliseconds:INFINITE:表示无限等待,否则可以设置时间(ms)

4. 等待多个资源对象:

DWORD WaitForMultipleObjects(DWORD nCount, CONST HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);

--nCount:句柄的数量

--*lpHandles:句柄数组

--bWaitAll:如果为TRUE则所有对象都空闲则获得权限,如果为FALSE则只要有一个对象空闲就获得权限

--dwMilliseconds:INFINITE:表示无限等待,否则可以设置时间(ms)

5. 等待多个资源对象,还可以等待消息:

DWORD MsgWaitForMultipleObjects(DWORD nCount, LPHANDLE pHandles, BOOL fWaitAll, DWORD dwMilliseconds, DWORD dwWakeMask);

6. 释放互斥器

BOOL ReleaseMutex(HANDLE hMutex);

7. 摧毁互斥器

BOOL CloseHandle(HANDLE hObject);

 

哲学家就餐:

我们知道,哲学家就餐问题就是为了解决所有老头都拿着一支筷子,但都在等待另外双筷子进行吃饭的尴尬场面。

比如一共5个哲学家,但也只有5支筷子。如果大家同时抓起一根筷子,很快就进入死锁场面;但如果不允许老头子拿起一根筷子,而是只允许一次拿起一双筷子,此时就可以保证至少2个老头能够先吃饭了,即使还留着一根筷子另外3个老头也只能傻等——这样就能避免大家都吃不到饭的问题

C++互斥器:Mutex

那么如何使用Mutex来对哲学家问题进行解决呢?

C++互斥器:Mutex,布布扣,bubuko.com

C++互斥器:Mutex

上一篇:JavaScript中JSONObject和JSONArray相关知识备忘(网络转载)


下一篇:java的一些基本概念