Исключения C++ и обработчики сигналов

Я читаю The Design and Evolution of C++ Бьерна Страуструпа. Что касается обработки исключений и асинхронных сигналов, это упоминается ниже:

Можно ли использовать исключения для обработки таких вещей, как сигналы? Почти наверняка не в большинстве сред C. Проблема в том, что C использует такие функции, как malloc, которые не являются реентерабельными. Если прерывание происходит в середине malloc и вызывает исключение, невозможно предотвратить повторное выполнение обработчиком исключения malloc.

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

Что автор имеет в виду под утверждением, что невозможно предотвратить повторное выполнение обработчиком исключений malloc? Как сделать функции повторно входящими, чтобы можно было генерировать исключения из обработчиков сигналов?


person venkysmarty    schedule 30.06.2011    source источник


Ответы (3)


На мой взгляд, эта часть не имеет особого смысла с текущим C++.

В C++ нет способа использовать исключение в качестве сигнала, потому что сигналы предназначены для выполнения обработчика, а затем (возможно) продолжают выполнение.

Однако исключения C++ не работают таким образом. Как только вы доберетесь до обработчика исключений, стек уже будет откатан, и нет возможности «продолжить» после обработки: нет способа добраться до оператора после броска (или после вызова функции, во время которого возникает исключение). бросил).

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

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

Может быть, в раннем дизайне С++ была опция возобновления для исключений...

person 6502    schedule 30.06.2011
comment
Замечательно, что вы указали, что выполнение программы не может быть продолжено после того, как выброшенное исключение не будет перехвачено. - person Buğra Ekuklu; 03.11.2015

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

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

person Mark B    schedule 30.06.2011

Функция является «реентерабельной», если она может быть прервана в середине выполнения и вызвана снова до завершения прерванного вызова. Другой способ взглянуть на это: реентерабельная функция может быть вызвана из обработчика сигнала. Все ставки сняты при вызове нереентерабельной функции из обработчика сигнала. Единственными функциями, которые следует вызывать из обработчика сигналов, являются те функции, которые известны как реентерабельные.

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

Другая проблема с обработчиками сигналов по сравнению с исключениями: код, выполняемый в обработчике сигналов, по существу выполняется в другом потоке, чем основной код. Если сигнал может быть адресован, возврат из обработчика сигнала возвращает сразу после точки, где был поднят сигнал. Как вы собираетесь генерировать исключение в обработчике сигнала? Сделайте это, и обработчик сигнала больше не возвращается! Это означает, что остальная часть выполнения эффективно выполняется внутри обработчика сигнала. Что происходит, когда появляется другой сигнал? Эти две концепции просто несовместимы. Реентерабельность — это лишь верхушка айсберга.

person David Hammen    schedule 30.06.2011