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

 /* Определение поступившего сигнала */

 signal_waiting = 0;

 /* Обработка сигнала */

}

К сожалению, этот код изобилует условиями гонки:

for (;;) {

 if (!signal_waiting) {

  /* <--- Сигнал может появиться здесь, после проверки условия! */

  pause(); /* pause() будет вызвана в любом случае */

  signal_waiting = 1;

 }

 /* Определение поступившего сигнала

    <--- Сигнал может переписать здесь глобальные данные */

 signal_waiting = 0;

 /* Обработка сигнала

    <--- То же и здесь, особенно для нескольких сигналов */

}

Решением является блокирование интересующего сигнала в любое время, кроме ожидания его появления. Например, предположим, что интересующим нас сигналом является SIGINT:

void handler(int sig) {

 /* sig автоматически блокируется функцией sigaction() */

 /* Установить глобальные данные, касающиеся этого сигнала */

}

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

 sigset_t set;

 struct sigaction act;

 /* ...обычная настройка, опции процесса и т.д. ... */

 sigemptyset(&set); /* Создать пустой набор */

 sigaddset(&set, SIGINT); /* Добавить в набор SIGINT */

 sigprocmask(SIG_BLOCK, &set, NULL); /* Заблокировать его */

 act.sa_mask = set; /* Настроить обработчик */

 act.sa_handler = handler;

 act.sa_flags = 0;

 sigaction(sig, &act, NULL); /* Установить его */

 ... /* Возможно, установить отдельные обработчики */

 ... /* для других сигналов */

 sigemptyset(&set); /* Восстановить пустой, допускает SIGINT */

 for (;;) {

  sigsuspend(&set); /* Ждать появления SIGINT */

  /* Обработка сигнала. SIGINT здесь снова блокируется */

 }

 /* ...любой другой код... */

 return 0;

}

Ключом к использованию этого является то, что sigsuspend() временно заменяет маску сигналов процесса маской, переданной в аргументе. Это дает SIGINT возможность появиться. При появлении он обрабатывается; обработчик сигнала возвращается, а вслед за ним возвращается также sigsuspend(). Ко времени возвращения sigsuspend() первоначальная маска процесса снова на месте.

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

При наличии всего этого не следует в новом коде использовать pause(). pause() был стандартизован POSIX главным образом для поддержки старого кода. То же самое верно и для функции sigpause() System V Release 3. Вместо этого, если нужно структурировать свое приложение с использованием сигналов для IPC, используйте исключительно функции API sigsuspend() и sigaction().

ЗАМЕЧАНИЕ. Приведенный выше код предполагает, что маска сигналов процесса начинается пустой. Код изделия должен вместо этого работать с любой маской сигналов, имеющейся на момент запуска программы.

<p>10.8. Важные сигналы специального назначения</p>

Некоторые сигналы имеют особое назначение. Здесь мы опишем наиболее важные.

<p>10.8.1. Сигнальные часы: <code>sleep()</code>, <code>alarm()</code> и <code>SIGALARM</code></p>

Часто бывает необходимо написать программу в виде

while (/* некоторое неверное условие */) {

 /* подождать некоторое время */

}

Часто такая потребность возникает в сценариях оболочки, например, в ожидании регистрации определенного пользователя:

until who | grep '^arnold' > /dev/null

do

 sleep 10

done

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

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

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

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

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

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

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

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

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

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