嵌套关键部分是否有效?

时间:2011-08-31 16:41:35

标签: c++ winapi critical-section

例如,这是否有效?

CRITICAL_SECTION cs;

::InitializeCriticalSection( &cs );

::EnterCriticalSection( &cs );      // First level
::EnterCriticalSection( &cs );        // Second level

/* do some stuff */

::LeaveCriticalSection( &cs );        // Second level
::LeaveCriticalSection( &cs );      // First level

::DeleteCriticalSection( &cs );

显然,我绝不会故意这样做,但是如果这是由于函数调用而产生的,那么“第一级”被调用来锁定一个复杂(例如搜索)算法的对象和“第二级“在该对象的访问者函数中被调用?

3 个答案:

答案 0 :(得分:29)

是的,在其内部输入相同的关键部分是有效的。来自the docs

  

在线程拥有关键部分的所有权后,它就可以生成   对EnterCriticalSection或TryEnterCriticalSection的额外调用   没有阻止它的执行。这可以防止线程   在等待关键部分时它会自行死锁   已经拥有。线程每次都进入临界区   EnterCriticalSection和TryEnterCriticalSection成功。一个帖子   必须在每次进入时调用LeaveCriticalSection一次   关键部分。

答案 1 :(得分:10)

来自documentation

  

在线程拥有关键部分的所有权后,它可以对EnterCriticalSection或TryEnterCriticalSection进行额外调用,而不会阻止其执行。这可以防止线程在等待它已经拥有的关键部分时自行死锁。每次EnterCriticalSection和TryEnterCriticalSection成功时,线程都会进入临界区。每次进入临界区时,线程必须调用一次LeaveCriticalSection。

答案 2 :(得分:1)

验证其他两个帖子。快速查看WinDbg中的Critical部分显示cricital部分维护一个整数变量来保存递归计数。

0:001> dt RTL_CRITICAL_SECTION
+0x000 DebugInfo : Ptr32 _RTL_CRITICAL_SECTION_DEBUG
+0x004 LockCount : Int4B
+0x008 RecursionCount : Int4B
+0x00c OwningThread : Ptr32 Void
+0x010 LockSemaphore : Ptr32 Void
+0x014 SpinCount : Uint4B 

RecursionCount - 线程可以多次获取关键部分。这个领域 表示同一线程获取临界区的次数。通过 默认情况下,该字段的值为0,表示没有线程拥有 关键部分。