Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек СРВ от Анн.doc
Скачиваний:
11
Добавлен:
09.11.2019
Размер:
2.26 Mб
Скачать

Лекция № 6.

Связь между процессами000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000имер000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 посредством proxies. Сигналы и сообщения.

План лекции.

1. IPC посредством proxies

2. IPC посредством сигналов

3. Сигналы и сообщения.

1. IPC посредством proxies

Proxy - это форма не блокирующего сообщения, которая очень подходит для извещения о событиях, когда процесс-отправитель не собирается работать с получателем. Единственная функция proxy -- это посылать стандартные сообщения конкретному процессу, который владеет этим proxy. Так же как и предыдущий вид IPC -- сообщения (messages), proxy могут работать и по сети.

Используя proxy, процесс или обработчик прерываний может посылать сообщения другому процессу без блокировки и ожидания какого-либо ответа. Вот несколько примеров использования proxу:

• Один процесс хочет известить другой процесс о наступлении какого-то события, но не может позволить себе оставаться заблокированным на посылку пока получатель не выдаст Receive() и Reply().

• Один процесс хочет послать другому некие данные, но не нуждается в ответе или в каком-либо другом подтверждении получения их.

• Обработчик прерываний хочет сообщить процессу, что появились данные для обработки.

Proxy создаются при помощи функции языка С qnx_proxy_attach(). Любой процесс (кроме родительского) или обработчик прерываний знающий идентификатор proxy может заставить proxy доставить его заранее определенное сообщение, используя функцию С Trigger(). Запросы Trigger() обрабатывает Kernel. Будем называть это активацией proxy.

Proxy может быть активирован многократно, и он будет посылать свое сообщение каждый раз, когда активирован. Длина очереди таких сообщений, которые надо доставить, может достигать 65,535.

client 3 2 1 proxy

"canned message" 3

"canned message" 2

"canned message" 1

server

Клиентский процесс активирует proxy три раза, что приводит к получению сервером трех "законсервированных сообщений" от proxy (типа шютка автора прим. пер.).

2. IPC посредством сигналов

Сигналы это традиционный метод асинхронной связи, который присутствует во многих операционных системах на протяжении многих лет.

QNX поддерживает богатый набор POSIX-совместимых сигналов в добавления к специальным QNX сигналам и традиционным сигналам UNIX-оидных систем.

Считается, что сигнал дошел до процесса, когда тот предпринял какое-либо определенное действие в ответ на него. Процесс может так же сам послать сигнал.

Генерация сигналов

Если ты хочешь:

то используй:

генерировать сигнал от оболочки

kill или slay утилиты

генерировать сигнал изнутри процесса

kill() или raise() функции С

Получение сигналов

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

  • Если нет никаких настроек для обработки сигнала - то работа происходит по умолчанию. Обычное действие по умолчанию – прекратить процесс.

  • Процесс может игнорировать сигнал. Если настройка такова - то процесс ничего не предпримет по получению сигнала (обратите внимание что сигналы SIGCONT, SIGKILL и SIGSTOP не могут быть проигнорированы при нормальных обстоятельствах).

  • Процесс может иметь обработчик сигналов для полуученого сигнала— обработчик сигналов это функция в процессе, которая начинает работать по приходу сигнала. Когда у процесса есть обработчик сигналов для конкретного сигнала - говорят, что процесс способен "отловить" сигнал. Любой процесс "отловивший" сигнал в результате получает некий вид программного прерывания. С сигналом не передается никаких данных.

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

Обобщение сигналов

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

Стандартные сигналыОтловить/ игнорироватьДействие по

умолчанию

Описание

SIGABRTдаПрекратить процесс

Сигнал ненормального завершения, такой как выдает функция abort()

SIGALRMДа"

Сигнал окончания времени такой как выдает alarm()

SIGFPE**Да"

Неправильная математическая операция (целое или с плав. точкой) типа деления на ноль или переполнение

SIGHUPДа"

Смерть сессионного лидера (session leader), или отключение на контролирующем терминале

SIGILL**Да"

Обнаружение ошибочной аппаратной инструкции

SIGINTДа"

Интерактивный сигнал внимания (<Break>)

SIGKILL*Да"

Сигнал завершения, должен выдаваться только чрезвычайными

SIGPIPEДа"

Попытка работать с pipe который никто не читает

SIGQUITДа"

Интерактивный сигнал прекращения

SIGSEGV**Да"

Обнаружение неправильной ссылки на память

SIGTERMДа"

Сигнал прекращения

SIGUSR1Да"

Зарезервирован как сигнал для приложений номер 1

SIGUSR2Да"

Зарезервирован как сигнал для приложений номер 2

Сигналы для контроля за работой

СигналОтловить/ игнорироватьДействие по умолчанию

Описание

SIGCHLD ДаИгнорировать сигнал

Дочерний процесс прекращен

SIGCONTНетПродолжать процесс HELD ; игнорировать сигнал если процесс не HELD

Продолжать если HELD

SIGSTOP*НетПриостановить процесс

HOLD сигнал процесса

SIGTSTP*НетИгнорировать сигнал

Не поддерживается QNX

SIGTTINНет-"-

-"-

SIGTTOUНет-"-

-"-

Специфические сигналы QNX

СигналОтловить/ игнорироватьДействие по умолчанию

Описание

SIGBUS**ДаПрекратить процесс

Обозначает ошибку паритета в памяти (специфическая интерпретация QNX)

SIGDEVДа-"-

Генерируется когда значительное и запрошенное событие происходит в Device Manager

SIGPWRДа-"-

Запрошена "мягкая" перезагрузка <Ctrl>-<Alt>-<Shift>-<Del> или утилита shutdown

Традиционные сигналы UNIX

СигналОтловить/ игнорироватьДействие по умолчанию

Описание

SIGIOT+ДаПрекратить процесс

Инструкция IOT

SIGSYS+Да-"-

Неправильный аргумент системного вызова

SIGWINCH+Да-"-

Смена окна

SIGURG+Да-"-

Особая ситуация на сокете

SIGPOLL+Да-"-

Произошло опрашиваемое событие

SIGEMT+Да-"-

инструкция EMT (эмулятор ловушка)

SIGTRAPДа-"-

Неподдерживаемое

* Сервер может защитить себя от подобных сигналов используя функцию С qnx_pflags(). Для этого сервер должен иметь superuser привилегии.

** Если происходит вторая такая же ошибка пока процесс находится в обработчике сигнала ошибки - то процесс будет прекращен.

+ Этот сигнал определен для совместимости с некоторыми ранними системами UNIX; он не генерируется какими либо QNX компонентами.

Определение обработки сигналов

Для определения типа обработки для каждого сигала используется функция ANSI C signal() или функция POSIX sigaction().

Функция sigaction() предоставляет больше контроля над средой обработки сигналов.

Тип обработки сигналов можно изменить в любое время. Если вы изменили настройку обработчика на игнорирование сигнала - то все ожидающие сигналы этого типа будут сброшены.

Отлов сигналов

Надо учитывать некоторые моменты относительно процессов, которые отлавливают сигналы с помощью функции обработки сигналов.

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

Если процесс не возвращается из обработчика сигналов - то он может использовать следующие функции С: либо siglongjmp() либо longjmp(), но предпочтительнее siglongjmp(). При использовании longjmp() сигнал остается заблокированным.

Безопасные функции для обработчиков сигналов

Библиотечные функции POSIX и ANSI C безопасны для использования в обработчиках сигналов. Вам не следует пытаться использовать другие библиотечные функции, поскольку результат будет непредсказуемым. По тем же причинам не надо использовать в вашей программе пользовательские функции за исключением случаев когда они re-entrant.

_exit{)

access()

аlarm()

cfgetispeed()

cfgetospeed()

cfsetispeed()

cfsetospeed()

chdir()

chmod()

chown()

close()

creat()

dup2()

dup()

execle()

execve()

fcntl()

fork()

fstat()

getegid()

geteuid()

getgid()

getgroups()

getpgrp()

getpid()

getppid()

getuid()

kill()

link()

Iseek()

mkdir()

mkfifo()

open()

pathconf())

pause()

pipe()

read()

rename()

rmdir()

setgid()

setpgid()

setsid()

setuid()

sigaction()

sigaddset()

sigdelset()

sigemptyset()

sigfillset()

sigismember()

signal()

sigpending()

sigprocmask()

sigsuspend()

sleep()

stat()

sysconf()

tcdrain()

tcflow()

tcflush()

tcgetattr()

tcgetpgrp()

tscendbreak()

tcsetattr()

tcsetgrp()

time()

times()

umask()

uname()

unlink()

ustat()

utime()

wait()

waitpid()

write()

Блокировка сигналов

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

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

Некоторые системы UNIX имеют испорченную реализацию обработчиков сигналов в том плане, что они перенастраивают сигнал на действие по умолчанию вместо блокировки. Как результат некоторые UNIX приложения вызывают функцию signal() в обработчике сигналов, чтобы настроить его как было. Тут есть два источника ошибок. Во-первых, если в момент, когда ваша программа в обработчике, но еще не вызвала signal(), приходит другой сигнал, то программа может быть убита. Во-вторых, если сигнал приходит сразу же после вызова signal() то вы можете рекурсивно войти в обработчик. QNX поддерживает блокировку сигналов и поэтому свободна от этих проблем. Вам не надо вызывать signal() в вашем обработчике. Если вы покидаете ваш обработчик длинным переходом - то вы должны использовать функцию siglongjmp().

3. Сигналы и сообщения.

Существует важная взаимосвязь между сигналами и сообщениями. Если ваш процесс заблокирован на прием или на получение в момент генерации сигнала - и у вас есть обработчик сигнала - произойдут следующие действия:

1) процесс разблокируется

2) произойдет обработка сигнала

3) Send() или Receive() вернет ошибку

Если ваш процесс был заблокирован на отправку - это не представляет проблемы, так как получатель еще не получил сообщение. Но если процесс был заблокирован на ответ - то вы не будете знать: было ли обработано посланное сообщение и запускать ли еще раз Send()

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

• нормально завершить первый запрос — отправителю гарантировано, что его сообщение было должным образом обработано

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

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