在函数和子函数中调用相同的临界区

Same critical section being called in function and subfunction

我是一名支持工程师,在失败进程的转储中,我看到有一些锁。

使用 Windbg(Visual Studio 无法正确处理调用堆栈)我发现一个函数 (ClassName::F()) 正在恢复。该函数使用一个临界区并调用一个子函数(ClassName::f_sub()),子函数调用相同的临界区,简而言之:

int ClassName::f_sub(){
  EnterCriticalSection(&m_cs);
  ...
  LeaveCriticalSection(&m_cs);
  return ...;
}

int ClassName::F() {
  EnterCriticalSection(&m_cs);
  ...
  int temp = f_sub();
  ...
  LeaveCriticalSection(&m_cs);
  return ...;
}

每次都使用相同的临界区 m_csClassName 的 属性)。

在我看来,这使得以下顺序成为可能:

Thread 1 : F()     : Enter the critical section. (Thread 1 is in)
Thread 1 : f_sub() : Enter the critical section. (Thread 1 is in)
Thread 1 : f_sub() : Leave the critical section. (Thread 1 is out)
Thread 2 : F()     : Enter the critical section. (Thread 2 is in) 

=> WRONG! Thread 2 should be forced to wait for Thread 1 leaving the critical section via F().

我的分析是否正确,这是否意味着建议对主函数和子函数使用不同的临界区?

Is my analysis correct and does this mean that it's advised to have different critical sections for main and sub functions?

来自 Microsoft Docs(强调我的):

After a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns. The thread enters the critical section each time EnterCriticalSection and TryEnterCriticalSection succeed. A thread must call LeaveCriticalSection once for each time that it entered the critical section.

所以不,你描述的事情不应该发生。多次进入临界区是完全没问题的,离开临界区的次数也一样。