Читаем Linux программирование в примерах полностью

Оба случая относятся к состоянию гонки. Одним решением для этих проблем является как можно большее упрощение обработчиков сигналов. Это можно сделать, создав флаговые переменные, указывающие на появление сигнала. Обработчик сигнала устанавливает переменную в true и возвращается. Затем основная логика проверяет флаговую переменную в стратегических местах:

int sig_int_flag = 0; /* обработчик сигнала устанавливает в true */

void int_handler(int signum) {

 sig_int_flag = 1;

}

int main(int argc, char **argv) {

 bsd_signal(SIGINT, int_handler);

 /* ...программа продолжается... */

 if (sig_int_flag) {

  /* возник SIGINT, обработать его */

 }

 /* ...оставшаяся логика... */

}

(Обратите внимание, что эта стратегия уменьшает окно уязвимости, но не устраняет его).

Стандарт С вводит специальный тип — sig_atomic_t — для использования с такими флаговыми переменными. Идея, скрывающаяся за этим именем, в том, что присвоение значений переменным этого типа является атомарной операцией: т.е. они совершаются как одно делимое действие. Например, на большинстве машин присвоение значения int осуществляется атомарно, тогда как инициализация значений в структуре осуществляется либо путем копирования всех байтов в (сгенерированном компилятором) цикле, либо с помощью инструкции «блочного копирования», которая может быть прервана. Поскольку присвоение значения sig_atomic_t является атомарным, раз начавшись, оно завершается до того, как может появиться другой сигнал и прервать его.

Наличие особого типа является лишь частью истории. Переменные sig_atomic_t должны быть также объявлены как volatile:

volatile sig_atomic_t sig_int_flag = 0; /* обработчик сигнала устанавливает в true */

/* ...оставшаяся часть кода как раньше... */

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

Структурирование приложения исключительно вокруг переменных sig_atomic_t ненадежно. Правильный способ обращения с сигналами показан далее, в разделе 10.7 «Сигналы для межпроцессного взаимодействия».

<p>10.4.6. Дополнительные предостережения</p>

Стандарт POSIX предусматривает для обработчиков сигналов несколько предостережений:

• Что случается, когда возвращаются обработчики для SIGFPE, SIGILL, SIGSEGV или любых других сигналов, представляющих «вычислительные исключения», не определено.

• Если обработчик был вызван в результате вызова abort(), raise() или kill(), он не может вызвать raise(). abort() описана в разделе 12.4 «Совершение самоубийства: abort()», a kill() описана далее в этой главе. (Описанная далее функция API sigaction() с обработчиком сигнала, принимающая три аргумента, дает возможность сообщить об этом, если это имеет место.)

• Обработчики сигналов могут вызвать лишь функции из табл. 10.2. В частности, они должны избегать функций . Проблема в том, что во время работы функции может возникнуть прерывание, когда внутреннее состояние библиотечной функции находится в середине процесса обновления. Дальнейшие вызовы функций могут повредить это внутреннее состояние.

Список в табл. 10.2 происходит из раздела 2.4 тома System Interfaces (Системные интерфейсы) стандарта POSIX 2001. Многие из этих функций относятся к сложному API и больше не рассматриваются в данной книге.

Таблица 10.2. Функции, которые могут быть вызваны из обработчика сигнала

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных