C ++ исключения и обработчики сигналов - PullRequest
4 голосов
/ 30 июня 2011

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

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

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

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

Ответы [ 3 ]

4 голосов
/ 30 июня 2011

По моему мнению, эта часть не имеет особого смысла с нынешним C ++.

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

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

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

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

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

3 голосов
/ 30 июня 2011

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

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

1 голос
/ 30 июня 2011

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

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

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

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