Вход/Регистрация
QNX/UNIX: Анатомия параллелизма
вернуться

Цилюрик Олег Иванович

Шрифт:

9. Согласно POSIX сигналы, обработчики для которых также устанавливаются с флагом

SA_SIGINFO
, но не входящие в диапазон сигналов реального времени, например стандартные сигналы UNIX, могут обрабатываться как на основе помещения их в очередь, так и без ее использования; выбор оставляется на усмотрение разработчика ОС.

Мы перечислили основные требования POSIX к модели обработки сигналов реального времени. Дополнения, отличия и специфические структуры данных QNX будут рассмотрены немного позже.

Весьма доходчивый пример для проверки и иллюстрации обработки сигналов реального времени приведен У. Стивенсом [2]. Мы же построим приложение, реализующее его основную идею: [33]

Приоритеты сигналов реального времени

#include <stdlib.h>

#include <stdio.h>

#include <iostream.h>

#include <signal.h>

#include <unistd.h>

33

Повторить приложение У. Стивенса в QNX в чистом виде не удастся — оно аварийно завершится по сигналу. Тонкий анализ этого факта интересен сам по себе, но он выходит за рамки нашего рассмотрения. Мы обращаем внимание на это обстоятельство, чтобы лишний раз сделать акцент на достаточно ощутимых отличиях реализаций QNX от схем POSIX (или того, как эти схемы понимаются в других ОС).

static void handler(int signo, siginfo_t* info, void* context) {

cout << "received signal " << signo << " code = " << info->si_code <<

" val = " << info->si_value.sival_int << endl;

}

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

cout << "signal SIGRTMIN=" << (int)SIGRTMIN

<< " - signal SIGRTMAX=" << (int)SIGRTMAX << endl;

int opt, val, beg = SIGRTMAX, num = 3,

fin = SIGRTMAX - num, seq = 3;

// обработка параметров запуска:

while ((opt = getopt(argc, argv, "b:e n")) != -1) {

switch(opt) {

case 'b': // начальный сигнал серии

if (sscanf(optarg, "%i", &val) != 1)

perror("parse command line failed"), exit(EXIT_FAILURE);

beg = val;

break;

case 'e': // конечный сигнал серии

if (sscanf(optarg, "%i", &val) != 1)

perror("parse command line failed"), exit(EXIT_FAILURE);

fin = val;

break;

case 'n': // количество сигналов в группе посылки

if (sscanf(optarg, "%i", &val) != 1)

perror("parse command line failed"), exit(EXIT_FAILURE);

seq = val;

break;

default:

exit(EXIT_FAILURE);

}

}

num = fin - beg;

fin += num > 0 ? 1 : -1;

sigset_t sigset;

sigemptyset(&sigset);

for (int i = beg; i != fin; i += (num > 0 ? 1 : -1))

sigaddset(&sigset, i);

pid_t pid;

// вот здесь ветвление на 2 процесса

if (pid - fork == 0) {

// дочерний процесс, здесь будут приниматься посланные сигналы

sigprocmask(SIG_BLOCK, &sigset, NULL);

for (int i = beg; i != fin; i += (num > 0 ? 1 : -1)) {

struct sigaction act, oact;

sigemptyset(&act.sa_mask);

act.sa_sigaction = handler;

// вот оно - реальное время!

act.sa_flags = SA_SIGINFO;

if (sigaction(i, &act, NULL) < 0) perror("set signal handler: ");

  • Читать дальше
  • 1
  • ...
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: