Схема уведомления

Схема уведомления

Как получить уведомление о тайм-ауте? При использовании таймера задержки вы получаете уведомление просто посредством возвращения в состояние READY.

При использовании периодически и однократных таймеров у вас появляется выбор:

• послать импульс;

• послать сигнал:

• создать поток.

Импульсы мы уже обсуждали главе «Обмен сообщениями»; сигналы — стандартный для UNIX механизм. Здесь же мы кратко рассмотрим уведомления при помощи создания потока.

Как заполнять структуру struct sigevent

Независимо от выбранной вами схемы уведомления, вам обязательно придется заполнять структуру struct sigevent. Давайте вкратце посмотрим, как это делается.

struct sigevent {

 int sigev_notify;

 union {

  int  sigev_signo;

  int  sigev_coid;

  int  sigev_id;

  void (*sigev_notify_function)(union sigval);

 };

 union sigval sigev_value;

 union {

  struct {

   short sigev_code;

   short sigev_priority;

  };

  pthread_attr_t *sigev_notify_attributes;

 };

};

Обратите внимание, что в приведенной декларации используются неименованные объединения и структуры. Внимательное изучение файла заголовка покажет вам, как этот трюк проходит с компиляторами, не поддерживающими такую особенность. По существу там есть директива #define, которая заставляет именованные объединения и структуры выглядеть неименованными. Подробнее см. <sys/siginfo.h>.

Первое поле, которое вы должны заполнить, — это элемент sigev_notify, который определяет выбранный вами тип уведомления:

SIGEV_PULSE

Будет передан импульс.

SIGEV_SIGNAL, SIGEV_ SIGNAL _CODE или SIGEV_SIGNAL_THREAD

Будет передан сигнал.

SIGEV_UNBLOCK

В данном случае не используется; предназначен для тайм-аутов ядра (см. ниже в разделе «Тайм-ауты ядра»).

SIGEV_INTR

В данном случае не используется; предназначен для прерываний (см. главу «Прерывания»),

SIGEV_THREAD

Будет создан поток.

Поскольку мы намерены использовать структуру struct sigevent для таймеров, нас будут интересовать только такие значения sigev_notify как SIGEV_PULSE, SIGEV_SIGNAL* и SIGNAL_THREAD; остальные мы рассмотрим в соответствующих их применению разделах.

Уведомление при помощи импульса

Чтобы передать импульс при срабатывании таймера, присвойте полю sigev_notify значение SIGEV_PULSE и обеспечьте немного дополнительной информации:

Поле Значение и смысл
sigev_coid Идентификатор соединения (connection ID), по каналу которого которому будет передан импульс.
sigev_value 32-разрядное значение (данные импульса — см. параграф «Что внутри импульса?», глава «Обмен сообщениями» — прим. ред.), которое будет передано по заданному полем sigev_coid соединению.
sigev_code 8-разрядное значение (код импульса — см. параграф «Что внутри импульса?», глава «Обмен сообщениями» — прим. ред.), которое будет передано по заданному полем sigev_coid соединению.
sigev_priority Приоритет доставки импульса. Нулевое значение не допускается — слишком уж много людей пострадало от переключения на нулевой приоритет после получения импульса, а поскольку на этом приоритете приходится конкурировать за процессор со спецпроцессом IDLE, много процессорного времени там точно не светит :-).

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

Уведомление при помощи сигнала

Чтобы передать сигнал, укажите в поле sigev_notify одно из нижеперечисленных значений:

SIGEV_SIGNAL

Процессу будет передан обычный сигнал.

SIGEV_SIGNAL_CODE

Процессу будет передан сигнал, содержащий 8-битный код.

SIGEV_SIGNAL_THREAD

Сигнал, содержащий 8-битный код, будет передан определенному потоку.

При выборе уведомления типа SIGEV_SIGNAL* нужно будет заполнить ряд дополнительных полей:

Поле Значение и смысл
sigev_signo Номер сигнала для передачи (берется из <signal.h>, например, SIGALRM).
sigev_code 8-разрядный код (для уведомления типа SIGEV_SIGNAL_CODE или SIGEV_SIGNAL_THREAD).

Уведомление созданием потока

Для создания потока по срабатыванию таймера установите поле sigev_notify в значение SIGEV_THREAD и заполните следующие поля:

Поле Значение и смысл
sigev_notify_function Адрес функции, возвращающей void* и принимающей void*, которая будет вызвана при возникновении события.
sigev_value Значение, которое будет передано функции sigev_notify_function() в качестве параметра.
sigev_notify_attributes Атрибутная запись потока (см. главу «Процессы и потоки», параграф «Атрибутная запись потока»).

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

Общие приемы программирования уведомлений

В файле <sys/siginfo.h> есть ряд удобных макросов упрощения заполнения полей в структурах:

SIGEV_SIGNAL_INIT(eventp, signo)

Установите eventp в SIGEV_SIGNAL и впишите соответствующий номер сигнала signo.

SIGEV_SIGNAL_CODE_INIT(eventp, signo, value, code)

Установите поле eventp в SIGEV_SIGNAL_CODE, укажите номер сигнала в signo, а также задайте значения полей value и code.

SIGEV_SIGNAL_THREAD_INIT(eventp, signo, value, code)

Установите eventp в SIGEV_SIGNAL_THREAD, укажите номер сигнала в signo, а также задайте значения полей value и code.

SIGEV_PULSE_INIT(eventp, coid, priority, code, value)

Установите eventp в SIGEV_SIGNAL_PULSE, укажите идентификатор соединения в coid, а также параметры priority, code и value. Отметьте, что для priority есть специальное значение SIGEV_PULSE_PRIO_INHERIT, которое предотвращает изменение приоритета принимающего потока.

SIGEV_UNBLOCK_INIT(eventp)

Установите eventp в SIGEV_UNBLOCK.

SIGEV_INTR_INIT(eventp)

Установите eventp в SIGEV_INTR.

SIGEV_THREAD_INIT(eventp, func, attributes)

Задайте значения eventp, функции потока func и атрибутной записи attributes.

Уведомление при помощи импульса

Предположим, что вы разрабатываете сервер, который будет обречен провести большую часть своей жизни в RECEIVE-блокированном состоянии, ожидая сообщение. Идеальным вариантом здесь было бы принять специальное сообщение, указывающее, что момент, которого мы так долго ждали, наконец настал.

Как раз при таком сценарии и надо использовать импульсы в качестве схемы уведомления. В разделе «Применение таймеров», представленном ниже, я приведу пример кода, который можно использовать для периодического получения импульсов.

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

В этом случае оправданным выбором является использование уведомления при помощи сигнала — возможно, даже с обработчиком. (Другой вариант, который мы обсудим позже, заключается в использовании тайм-аутов ядра; см. также параграф «_NTO_CHF_UNBLOCK» в главе «Обмен сообщениями»). В параграфе «Применение таймеров», представленном ниже, мы рассмотрим пример, использующий сигналы.

Если вы вообще не собираетесь принимать сообщения, то использование сигнала и функции sigwait() является более экономной альтернативой созданию канала для принятия импульсного сообщения.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Схема data:URI

Из книги Разгони свой сайт автора Мациевский Николай

Схема data:URI Схема data:URI предоставляет способ для внедрения «непосредственно данных» точно так же, как если бы они были подключены через вызовы внешних файлов. Синтаксис у нее следующий:data:[<тип данных>][;base64],<данные>В случае простых изображений вам нужно указать


Схема документа

Из книги Word 2007.Популярный самоучитель автора Краинский И

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


Схема WS XML

Из книги Windows Script Host для Windows 2000/XP автора Попов Андрей Владимирович

Схема WS XML Синтаксис элементов, составляющих структуру WS-файла, в общем виде можно представить следующим образом:<element [attribute1="value1" [attribute2="value2" ... ]]> Содержимое (content)</element>Открывающий тег элемента состоит из следующих компонентов:? открывающей угловой скобки "<";?


Схема WSC XML

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Схема WSC XML Ранее в главе 3 отмечалось, что объектная модель, которая используется при создании многозадачных сценариев (WS-файлов), была в основном позаимствована из схемы WSC XML, поэтому многие элементы WSC-файлов окажутся вам знакомыми.В листинге 10.1 приводится несколько


Отправка уведомления порту завершения ввода/вывода

Из книги Стандарты программирования на С++. 101 правило и рекомендация автора Александреску Андрей

Отправка уведомления порту завершения ввода/вывода Поток может отправить в порт событие завершения вместе с ключом, чтобы завершить остающийся невыполненным вызов функции GetQueueCompletionStatus. Вся необходимая для этого информация предоставляется функцией PostQueueCompletionStatus.  BOOL


72. Для уведомления об ошибках следует использовать исключения

Из книги OrCAD PSpice. Анализ электрических цепей автора Кеоун Дж.

72. Для уведомления об ошибках следует использовать исключения РезюмеДля уведомления об ошибках лучше использовать механизм исключений, а не коды ошибок. Применять коды состояния (например, коды ошибок, переменную errno) следует только тогда, когда нельзя использовать


Схема ИЛИ-НЕ

Из книги Быстрые деньги в Интернете [50 способов заработать, сидя дома у компьютера] автора Парабеллум Андрей Алексеевич

Схема ИЛИ-НЕ В последнем примере главы 9 мы рассматривали логическую схему 7400: 2-входовую схему ИЛИ-НЕ. В качестве источников V1 и V2 были использованы источники напряжения типа PWL с выходным напряжением в виде последовательностей импульсов, представляющих уровни


Стандартная схема

Из книги Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform автора Кёртен Роб


Часы, таймеры и периодические уведомления

Из книги iOS. Приемы программирования автора Нахавандипур Вандад

Часы, таймеры и периодические уведомления В этой главе вы изучите системные часы, таймеры, и как заставить таймеры посылать вам сообщения. В ней также много практических советов и изобилие примеров


Глава 15. Уведомления

Из книги Linux Mint и его Cinnamon. Очерки применителя автора Федорчук Алексей Викторович

Глава 15. Уведомления 15.0. Введение Уведомления — это объекты, несущие определенную информацию, которая может передаваться множеству получателей методом широковещания. Уведомления очень удобны для разделения работы на относительно самостоятельные фрагменты кода, но


15.9. Реагирование на пуш-уведомления

Из книги автора

15.9. Реагирование на пуш-уведомления Постановка задачи Проработав раздел 15.8, вы научились доставлять в ваше приложение пуш-уведомления, но не знаете, как реагировать на них в


9.14. Уведомления

Из книги автора

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


Конфиденциальность, Общие, Уведомления

Из книги автора

Конфиденциальность, Общие, Уведомления Общего между этими тремя модулями, пожалуй, только то, что они были переработаны при переходе на Cinnamon версии 2.4.Вся настройка конфиденциальности сводится к решению вопроса, запоминать ли открываемые файлы, и если запоминать —