Разблокировка критического раздела в случае исключений, не связанных с C ++ - PullRequest
0 голосов
/ 29 апреля 2009

В моем классе есть объект CCriticalSection для синхронизации исключений с методом. Я использую его с объектом CSingleLock следующим образом:

void f()
{
  try
   {
     CSingleLock lock(&m_synchronizer, TRUE);
     .....
     .....

   }

  catch(SomeException )
  {
  }

  catch(...)
  {
  }

}

Объект критической секции должным образом разблокируется, если какой-либо из операторов выдает исключение C ++, однако, если я получаю исключение любого другого типа (что-то вроде нарушения прав доступа), есть ли способ разблокировать критическую секцию? Я не думаю, что RAII поможет здесь, поскольку разматывание стека не происходит. Есть ли что-то, что я могу сделать, чтобы предотвратить выход критической секции из заблокированного состояния после выхода из функции f?

Ответы [ 5 ]

3 голосов
/ 29 апреля 2009

РЕДАКТИРОВАТЬ Обновление

Деструктор CSingleLock действительно разблокирует базовый критический раздел. Нарушения доступа и тому подобное называются исключениями SEH. Относительно того, будет ли деструктор работать перед лицом исключения SEH, зависит от конкретной среды. Есть некоторые приемы, которые можно сделать, чтобы этот сценарий работал.

Например, один из вариантов - перевести все исключения SEH в соответствующее исключение C ++. Я недавно писал в блоге о технике для достижения этой цели. Как только они все являются исключениями C ++, вызываемый деструктор гарантирован.

Но другой вопрос - зачем это делать? Когда вы сталкиваетесь с нарушением прав доступа, единственное, что может надежно сделать ваша программа, - это сбой.

2 голосов
/ 29 апреля 2009

Если вы используете MSVC, попробуйте скомпилировать с параметром командной строки /EHa, который отображает структурированные исключения Windows в исключения C ++ (документы C ++ иногда называют их «асинхронными» исключениями).

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

Вы также можете попробовать использовать ключевые слова __try, __except, __finally для самостоятельной работы с SEH.

1 голос
/ 29 апреля 2009

RAII здесь помогает. Самое важное, что здесь не нужно делать, это «выйти из области видимости» - это не обязательно просто раскрутка стека. При выходе из блока try, как обычно, так и через исключение, вызывается деструктор. Каждый раз, когда ваша переменная выходит из области видимости, вызывается ее деструктор.

Редактировать

Хм, похоже, вопрос был отредактирован, чтобы сосредоточиться на SEH (не C ++ исключений). В этом случае код деструктора может не сработать. Однако, как отмечали другие, большинство исключений, не относящихся к C ++, эквивалентны сбоям приложений. Возможно, нецелесообразно реагировать на эти исключения каким-либо вменяемым образом, кроме как в случае сбоя. В этом случае ваше приложение закрывается и ваш критический раздел все равно будет уничтожен.

См. Ответ @ JaredPar, чтобы найти хорошее решение для перевода исключений C SEH в исключения C ++ для Windows.

0 голосов
/ 13 мая 2009

AFAIK, вы НИКОГДА не должны использовать CCriticalSection или любой объект синхронизации MFC.

0 голосов
/ 29 апреля 2009

Если вам действительно нужно, чтобы ваше приложение выжило, когда определенная область кода выполняет нарушение прав доступа, вам следует рассмотреть возможность размещения этого кода в отдельном процессе.

Если код пытается читать или писать в местах, где он не разрешен, что может помешать его записи в другие части памяти вашего приложения, вызывая всевозможные неприятные проблемы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...