浏览 3060 次
锁定老帖子 主题:锁机制
精华帖 (0) :: 良好帖 (0) :: 新手帖 (8) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-12-31  
mutexes

锁住一个未被拥有的mutex,比锁住一个未被拥有的critical section 多 花费几乎100倍的时间。
因为critical section不需要进入操作系统核心,直接在user mode就可以进行操作。

mutexes可以跨进程使用。critical section只能在同一个进程中使用。

等待一个mutex时,你可以指定结束等待的时间长度,当时对于critical section则不行。

critical section                     Mutex
InitializeCriticalSection()   CreateMutex()/openMutex()
EnterCriticalSection() WaitForSingleObject()/WaitForMultipleObjects()/MsgWaitForMultipleObjects()
LeaveCriticalSection()        ReleaseMutex()
DeleteCriticalSection()       CloseHandle()

为了能够跨进程使用同一个mutex,可以在产生mutex时指定其名称。如果指定了名称,系统中的其他任何线程就可以使用这个名称来处理该mutex。

Windows核心对象具有引用计数

mutex具有引用计数,当不再需要一个mutex时,可以调用CloseHandle()将它关闭。mutex有一个引用计数(reference count).每次调用CloseHandle(),引用计数便减1,当引用计数达到0时,mutex便自动被系统清除掉。

mutex使用流程
1 有一个mutex,没有任何线程拥有它,处于非激发状态
2 某个线程调用WaitForSingleObject(),并指定该mutex handle为参数
3Win32于是将该mutex拥有权交给这个线程,然后将此mutex的状态短暂地设为激发状态,于是Wait..()函数返回
4 mutex立刻又被设定为非激发状态,使任何处于等待状态下的其他线程没有办法获得其拥有权。
5 获得该mutex之线程调用releaseMutex(),将mutex释放掉,于是循环回到第一场景,周而复始。

mutex的所有权并非值属于那个产生它的线程,而是那个最后对此mutex进行wait...()操作并且尚未进行releaseMutex()操作的线程。一次只能有一个线程拥有该mutex。

mutex是在其引用计数降为0时被操作系统摧毁的,每当线程对此mutex调用一次closeHandle(),或当此线程结束时,mutex的引用计数即下降1.

被舍弃的mutex
一个正常的程序中,线程绝对不应该在它即将结束前还拥有一个mutex,因为这意味着线程没有能够适当地清除其资源。有时候,线程可能没有在结束前调用releasemutex()。为了解决这个问题,mutex有一个非常重要的特性。这性质在各种同步机制中是独一无二的。如果线程拥有一个mutex而在结束前没有调用releasemutex(),mutex不会被摧毁。取而代之的是,该mutex会被视为"未被拥有"以及"未被激发",而下一个等待中的线程会被以WAIT_ABANDONED_0通知。

semaphore 信号量
semaphore的现值代表的意义是目前可用的资源数。如果semaphore的现值为1,表示还有一个锁定动作可以成功,如果现值为5,表示还有5个锁定动作可以成功。
每当一个锁定动作成功,semaphore的现值就会减一,可以使用任何一种Wait...()函数要求锁定一个semaphore,因此如果semaphore的现值不为0,wait...()函数会立刻返回。这和mutex很像,如果没有任何线程拥有mutex,wait...()会立即返回
如果锁定成功,也不会受到semaphore的拥有权。因为可以有一个以上的线程同时锁定一个semaphore,所以谈semaphore的拥有权是无意义的。一个线程可以反复调用Wait...()以产生新的锁定,这和mutex绝不相同;拥有mutex的线程不论再调用多少次Wait...()函数,也不会被堵塞住。
一旦semaphore的现值降到0,就表示资源已经耗尽,此时,任何线程如果调用Wait...()函数,必然需要等待,直到某个锁定被解除为止

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics