Тот же критический раздел вызывается в функции и подфункции - PullRequest
1 голос
/ 19 апреля 2019

Я работаю инженером поддержки, и в дампе сбойного процесса я вижу, что есть некоторые блокировки.

Использование 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_cs (свойствоиз ClassName).

По моему мнению, это делает возможным следующую последовательность:

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().

Является ли мой анализ правильным и означает ли это, что рекомендуется иметь различные критические разделы дляОсновные и вспомогательные функции?

1 Ответ

1 голос
/ 19 апреля 2019

Является ли мой анализ правильным, и означает ли это, что рекомендуется иметь разные критические разделы для основных и вспомогательных функций?

Из Документы Microsoft (выделено мое):

После того, как у потока есть владелец критической секции, он может делать дополнительные вызовы EnterCriticalSection или TryEnterCriticalSection, не блокируя его выполнение.Это предотвращает взаимную блокировку потока при ожидании критического раздела, которым он уже владеет.Поток входит в критическую секцию каждый раз, когда EnterCriticalSection и TryEnterCriticalSection завершаются успешно. Поток должен вызывать LeaveCriticalSection один раз для каждого входа в критическую секцию.

Поэтому нет, то, что вы описали, не должно происходить.Совершенно нормально входить в критическую секцию несколько раз, и требуется выходить из нее ровно столько раз.

...