WaitForSingleObject 和 EnterCriticalSection 效率比较
2010-07-21 11:48
441 查看
Microsoft Windows
平台中两种最常用的锁定方法为 WaitForSingleObject
和 EnterCriticalSection
。WaitForSingleObject
是一个过载 Microsoft API
,可用于检查和修改许多不同对象(如事件、作业、互斥体、进程、信号、线程或计时器)的状态。Wa
itForSingleObject
的一个不足之处是它会始终获取内核的锁定,因此无论是否获得锁定,它都会进入特权模式 (
环路 0)
。此 API
还进入 Windows
内核,即使指定的超时为 0
,亦如此。此锁定方法的另一不足之处在于,它一次只能处理 64
个尝试对某个对象进行锁定的线程。WaitForSingleObject
的优点是它可以全局进行处理,这使得此 API
能够用于进程间的同步。它还具有为操作系统提供锁定对象信息的优势,从而可以实现公平性及优先级倒置。
通过对关键代码段实施 EnterCriticalSection
和 LeaveCriticalSection API
调用,可以使用 EnterCriticalSection
。此 API
具有 WaitForSingleObject
所不具备的优点,因为只有存在锁定争用时,才会进入内核。如果不存在锁定争用,则此 API
会获取用户空间锁定,并且在未进入特权模式的情况下返回。如果存在争用,则此 API
在内核中所采用的路径将与 WaitForSingleObject
极其相似。
在低争用的情况下,由于 EnterCriticalSection
不进入内核,因此锁定开销非常低。
不足之处是 EnterCriticalSection
无法进行全局处理,因此无法为线程获取锁定的顺序提供任何保证。EnterCriticalSection
是一种阻塞调用,意味着只有线程获得对此关键区段的访问权限时,该调用才会返回。Windows
引入了
TryEnterCriticalSection
,TryEnterCriticalSection
是一种非阻塞调用,无论获得锁定与否都会立即返回。此外,EnterCriticalSection
还允许开发人员使用自旋计数对关键区段进行初始化,在回退前线程会按此自旋计数尝试获取锁定。通过使用 API InitializeCriticalSectionAndSpinCount
,完成初始化。自旋计数可以在此调用中进行设置,也可以在注册表中进行设置,以根据不同操作系统及其相应的线程量程对自旋进行更改。
如果存在锁定争用,则 EnterCriticalSection
和 WaitForSingleObject
都会进入内核。如果实现程度过高,从用户模式到特权模式的转换开销将会非常大。
EnterCriticalSection
和 WaitForSingleObject API
调用在对使用数千个周期的运算进行锁定时,通常不会影响性能。在这些情况下,锁定调用本身的开销不会如此突出。会导致性能降低的情况是粒度锁定,获得和释放此锁定要花费数百个周期。在这些情况下,使用用户级别锁定则非常有益。
为了说明在低争用的情况下 WaitForSingleObject
调用与 EnterCriticalSection
调用的开销情况,我们分别在 1
个和 2
个线程上运行了内存管理锁定内核
。在低争用的情况下,存在加速比 (WaitForSingleObject_Time / EnterCriticalSection_Time)
大约为 5
倍的性能之差。在 2
个线程持续争用的情况下,使用 EnterCriticalSection
和使用 WaitForSingleObject
之间的差别最小。在低争用的情况下存在性能差距的原因如下:WaitForSingleObject
在每次调用时都进入内核,而 EnterCriticalSection
只有当存在锁定争用时,才进入内核。
平台中两种最常用的锁定方法为 WaitForSingleObject
和 EnterCriticalSection
。WaitForSingleObject
是一个过载 Microsoft API
,可用于检查和修改许多不同对象(如事件、作业、互斥体、进程、信号、线程或计时器)的状态。Wa
itForSingleObject
的一个不足之处是它会始终获取内核的锁定,因此无论是否获得锁定,它都会进入特权模式 (
环路 0)
。此 API
还进入 Windows
内核,即使指定的超时为 0
,亦如此。此锁定方法的另一不足之处在于,它一次只能处理 64
个尝试对某个对象进行锁定的线程。WaitForSingleObject
的优点是它可以全局进行处理,这使得此 API
能够用于进程间的同步。它还具有为操作系统提供锁定对象信息的优势,从而可以实现公平性及优先级倒置。
通过对关键代码段实施 EnterCriticalSection
和 LeaveCriticalSection API
调用,可以使用 EnterCriticalSection
。此 API
具有 WaitForSingleObject
所不具备的优点,因为只有存在锁定争用时,才会进入内核。如果不存在锁定争用,则此 API
会获取用户空间锁定,并且在未进入特权模式的情况下返回。如果存在争用,则此 API
在内核中所采用的路径将与 WaitForSingleObject
极其相似。
在低争用的情况下,由于 EnterCriticalSection
不进入内核,因此锁定开销非常低。
不足之处是 EnterCriticalSection
无法进行全局处理,因此无法为线程获取锁定的顺序提供任何保证。EnterCriticalSection
是一种阻塞调用,意味着只有线程获得对此关键区段的访问权限时,该调用才会返回。Windows
引入了
TryEnterCriticalSection
,TryEnterCriticalSection
是一种非阻塞调用,无论获得锁定与否都会立即返回。此外,EnterCriticalSection
还允许开发人员使用自旋计数对关键区段进行初始化,在回退前线程会按此自旋计数尝试获取锁定。通过使用 API InitializeCriticalSectionAndSpinCount
,完成初始化。自旋计数可以在此调用中进行设置,也可以在注册表中进行设置,以根据不同操作系统及其相应的线程量程对自旋进行更改。
如果存在锁定争用,则 EnterCriticalSection
和 WaitForSingleObject
都会进入内核。如果实现程度过高,从用户模式到特权模式的转换开销将会非常大。
EnterCriticalSection
和 WaitForSingleObject API
调用在对使用数千个周期的运算进行锁定时,通常不会影响性能。在这些情况下,锁定调用本身的开销不会如此突出。会导致性能降低的情况是粒度锁定,获得和释放此锁定要花费数百个周期。在这些情况下,使用用户级别锁定则非常有益。
为了说明在低争用的情况下 WaitForSingleObject
调用与 EnterCriticalSection
调用的开销情况,我们分别在 1
个和 2
个线程上运行了内存管理锁定内核
。在低争用的情况下,存在加速比 (WaitForSingleObject_Time / EnterCriticalSection_Time)
大约为 5
倍的性能之差。在 2
个线程持续争用的情况下,使用 EnterCriticalSection
和使用 WaitForSingleObject
之间的差别最小。在低争用的情况下存在性能差距的原因如下:WaitForSingleObject
在每次调用时都进入内核,而 EnterCriticalSection
只有当存在锁定争用时,才进入内核。
相关文章推荐
- WaitForSingleObject 和 EnterCriticalSection 效率比较
- WaitForSingleObject 和 EnterCriticalSection 效率比较
- 多线程中的 WaitForSingleObject 与 EnterCriticalSection 性能比较
- WaitForSingleObject 与 EnterCriticalSection 性能比较
- [zz]多线程中的 WaitForSingleObject 与 EnterCriticalSection 性能比较
- CMutex、CCriticalSection、CSemaphore、CEvent、WaitForSingleObject 的小例子
- 多线程访问文件问题中WaitForSingleObject方法的使用,及其效率!
- WaitForSingleObject使用详解
- 信号量、互斥锁、条件变量(类似waitforsingleobject)
- WaitForSingleObject函数
- c++中WaitForSingleObject函数解析
- WaitForSingleObject的用法
- WaitForSingleObject
- WaitForSingleObject WaitForMultipleObjects 用法
- WaitForSingleObject
- WaitForSingleObject实际使用中犯的错
- WaitForSingleObject
- 多线程编程(1) - 认识等待函数 WaitForSingleObject
- WaitForSingleObject和CEvent用法
- Windows CreateEvent,SetEvent,WaitForSingleObject的用法