Троан Эрик В.
Шрифт:
12.3.1. Описание сигналов
Иногда приложения нуждаются в описании сигнала для отображения пользователю или помещения в журнал. Существуют три способа сделать это (см. главу 9). К сожалению, ни один из них не стандартизован.
Самый старый метод предусматривает применение
Следует отметить, что эта функция использует тот же список сигналов, что и
Библиотека GNU С, используемая Linux, предлагает еще один метод —
Подобно
12.4. Написание обработчиков сигналов
Хотя обработчик сигнала выглядит подобно обычной функции С, он не вызывается так, как она. Вместо того чтобы быть частью нормальной последовательности вызовов программы, обработчик вызывается ядром. Ключевое различие между этими двумя вещами заключается в том, что обработчик может быть вызван почти в любое время, даже во время выполнения отдельного оператора С! Есть только несколько ограничений того, когда система может вызвать обработчик сигнала, на который вы полагаетесь.
1. Семантика некоторых сигналов ограничивает, когда они могут быть посланы. Так, например,
2. Если процесс находится в процессе обработки некоторого сигнала, то обработчик сигнала не вызывается повторно для обработки того же сигнала, если только не была задана опция
65
Хотя пользователи могут посылать
3. Процесс может блокировать сигналы, когда выполняется часть кода, используя
Поскольку обработчики сигналов могут быть запущены почти в любое время, важно писать их так, чтобы они не делали никаких негарантированных предположений относительно остальной части программы, и чтобы они сами не изменяли ничего таким образом, что это могло бы запутать остальную программу, когда она возобновит выполнение.
Одним из наиболее важных моментов, за которым нужно следить, является модификация глобальных данных. Если только не делать этого аккуратно, возможно получение ситуации состязаний. Простейший способ обеспечить безопасность обновления глобальных данных — просто избегать его. Второй, и лучший, способ — это блокировка всех обработчиков сигналов, которые модифицируют определенные структуры данных, всякий раз, когда остальная часть кода модифицирует их, с тем, чтобы обеспечить одновременное манипулирование этими данными только одним сегментом кода одновременно.
Хотя обработчик сигнала может читать структуры данных, когда его прерывает другой читатель этих данных, все прочие комбинации являются небезопасными. Более безопасно обработчику сигнала модифицировать структуры данных, которые читает остальная часть программы, чем наоборот — обработчику сигналов читать структуры данных, которые остальная часть программы выполняет запись. Некоторые специализированные структуры данных спроектированы так, чтобы позволить параллельный доступ, но их описание выходит за круг тем, рассматриваемых в настоящей книге.