win32多线程 (四) Mutex
Mutex 用途和critical section 非常类似,不过Mutex是内核对象,速度比section慢。Mutexes可以跨进程使用。另外Mutex在等待的时候可以设置等待时间。
以下是两种对象的相关函数比较:
CRITICAL_SECTION Mutex 核心对象
--------------------------------------------------------------------------------------
InitializeCriticalSection() CreateMutex()
OpenMutex()
--------------------------------------------------------------------------------------
EnterCriticalSection() WaitForSingleObject()
WaitForMultipleObjects()
MsgWaitForMultipleObjects()
--------------------------------------------------------------------------------------
LeaveCriticalSection() ReleaseMutex()
--------------------------------------------------------------------------------------
DeleteCriticalSection() CloseHandle()
具体API使用,参考相关资料。这里说下OpenMutex(),我们可以指定一个名字,这个名字是系统其他程序也可见的,所以应该起个特别些的。我们可以用Op enMutex()打开,如果返回已经存在,我们就可以识别的了自己的程序是否已经被开启,这在一个软件只允许开启一个程序进程的时候比较好用,比如你不想自己的程序在系统中开启多个,就可以这么做了。
这里,解决哲学家进餐的问题,即5个傻子用5只筷子吃饭,如果一个人抓住一只就不松手的5个傻子吃饭的问题
HANDLE arrayHandles[5] = {0};//模拟5只筷子 for (int index = 0; index < 5; index++) { arrayHandles[index] = CreateMutex(NULL, FALSE,NULL); } // WaitForMultipleObjects(2, arrayHandles, TRUE, INFINITE);//傻子可以吃饭的条件是等到两只筷子都在手上的时候。 //,可以吃饭了
WaitForMultipleObjects() 修正前面讲到的SwapLists死锁问题
#0001 struct Node #0002 { #0003 struct Node *next; #0004 int data; #0005 }; #0006 #0007 struct List #0008 { #0009 struct Node *head; #0010 HANDLE hMutex; #0011 }; #0012 #0013 struct List *CreateList() #0014 { #0015 List *list = (List *)malloc(sizeof(struct List)); #0016 list->head = NULL; #0017 list->hMutex = CreateMutex(NULL, FALSE, NULL); #0018 return list; #0019 } #0020 #0021 void DeleteList(struct List *list) #0022 { #0023 CloseHandle(list->hMutex); #0024 free(list); #0025 } #0026 #0027 void SwapLists(struct List *list, struct List *list2) #0028 { #0029 struct List *tmp_list; #0030 HANDLE arrhandles[2]; #0031 #0032 arrhandles[0] = list1->hMutex; #0033 arrhandles[1] = list2->hMutex; #0034 WaitForMultipleObjects(2, arrHandles, TRUE, INFINITE); #0035 tmp_list = list1->head; #0036 list1->head = list2->head; #0037 list2->head = tmp_list; #0038 ReleaseMutex(arrhandles[0]); #0039 ReleaseMutex(arrhandles[1]); #0040 }