За пределы POSIX: сигналы в сети
За пределы POSIX: сигналы в сети
А теперь, «на закуску», посмотрим справочную информацию по системной команде kill (послать сигнал). Вы, должно быть, помните, что в QNX есть дополнительная возможность получить справку по любой команде системы, используя команду # use <имя-команды>. Более того, вы можете и в любое свое приложение встроить возможность получения интерактивной справки. Как это происходит, описано в [4]. Итак:
# use kill
kill - terminate or signal processes (POSIX)
kill [-signal_name|-signal_number] pid ...
kill -l
Options:
-signal_name Symbolic name of signal to send
-signal_number Integer representing a signal type
-l List symbolic signal names
-n node Kill processes on the specified node.
(/bin/kill only)
Where:
Valid signal names are:
SIGNULL SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP
SIGIOT SIGABRT SIGEMT SIGFPE SIGKILL SIGBUS
SIGSEGV SIGSYS SIGPIPE SIGALRM SIGTERM SIGUSR1
SIGUSR2 SIGCHLD SIGPWR SIGWINCH SIGURG SIGPOLL SIGSTOP SIGTSTP
SIGCONT SIGVTALARM SIGTTIN SIGTTOU
Note:
kill is also available as a shell builtin
Здесь нас ожидает сюрприз, который мы выделили в показанном фрагменте жирным шрифтом. И говорит эта строка о том, что в системе QNX сигнал может посылаться процессу, работающему на любом узле сети QNET. И это совершенно естественно, если вспомнить промелькнувшее выше замечание из технической документации, что сигнал в QNX - это пульс, то есть один из видов сообщений микроядра.
Таким образом, системная команда QNX kill (именно системная — /bin/kill, в отличие от встроенной формы kill командных интерпретаторов, которые строго следуют традициям UNIX, как и предупреждает выделенная нами строка) имеет возможность посылать сигналы любому процессу в сети. Тем не менее при рассмотрении прототипов вызовов kill() и sigqueue() мы не находим и следа параметра, предоставляющего возможность определить удаленный процесс. Тогда каким образом это делает команда kill? Совершенно верно: используя вызов native QNX API, который выглядит так (этот вызов, как и многие другие, имеет две формы, вторая из которых является безопасной в много- поточной среде):
#include <sys/neutrino.h>
int SignalKill(uint32_t nd, pid_t pid,
int tid, int signo, int code, int value);
int SignalKill_r(uint32_t nd, pid_t pid, int tid, int signo,
int code int value);
где nd — дескриптор сетевого узла QNET, на котором будут разыскиваться pid и tid. Для посылки сигнала локальному процессу (потоку) можно для nd указать 0, но лучше — определенную системой константу ND_LOCAL_NODE.
Примечание
Дескриптор узла в сети QNET — понятие относительное; он может быть получен, например, вызовом netmgr_strtond(). Но и здесь не все так просто:
• Дескриптор, соответствующий, скажем, узлу «host», полученный на узле «А», может иметь значение N, но дескриптор того же узла, полученный на узле «В», будет иметь уже значение M, то есть дескриптор узла — это «дескриптор сетевого узла X, как он видится с сетевого узла Y».
• Тот же дескриптор узла «host» может быть определен как имеющий значение N, но уже через несколько секунд он может «сменить» свое значение на M, то есть значения, полученные netmgr_strtond(), должны использоваться немедленно...
Эти и другие сложности относятся к особенностям программного использования QNET и требуют отдельного обстоятельного обсуждения. Однако они не являются предметом нашего текущего рассмотрения.
pid — PID процесса, которому направляется сигнал, pid может иметь и отрицательное значение, при этом положительное значение (-pid) идентифицирует группу процессов EGID, и сигнал будет отправлен всем процессам группы. При нулевом значении pid сигнал будет отправлен всем процессам группы процесса отправителя.
tid — 0 или TID потока, которому направляется сигнал. При указании tid сигнал будет доставляться только указанному потоку, а при tid = 0 — всем потокам процесса. Дальнейшая судьба сигнала в обоих случаях зависит от маскирования сигнала в потоке, как мы рассматривали ранее.
signo — номер сигнала (с ним неоднократно встречались выше).
code и value — код и значение, ассоциированные с сигналом (их мы тоже встречали при рассмотрении модели сигналов реального времени).
Как и обычно, внешнее различие (для программиста) основной формы SignalKill() и формы, безопасной в многопоточной среде, SignalKill_r() состоит в том, что:
• SignalKill() возвращает -1 в случае ошибки, а код ошибки заносится в errno; любой другой возврат является индикатором успешного выполнения;
• SignalKill_r() возвращает EOK в случае успеха, а в случае ошибки возвращается отрицательный код ошибки (тот же, который основная форма заносит в errno, но со знаком минус).
Возможны следующие коды ошибок, возвращаемые этими вызовами:
EINVAL — недопустимое числовое значение signo;
ESRCH — несуществующий адресат (pid или tid);
EPERM — процесс не имеет достаточных прав для посылки сигнала;
EAGAIN — недостаточно ресурсов ядра для выполнения запроса.
Для того чтобы получить работающий пример использования этой возможности, возьмите любой из приводившихся выше примеров, разнесите процессы по сетевым узлам и определите «целеуказание» в процессе-отправителе.
Простейшим примером и демонстрацией удаленной реакции в сети может быть следующая последовательность действий:
• Производим запуск задачи на удаленном узле, например:
# on -f <host> raqc
• После чего, выполнив ряд операций в запущенной программе, прекращаем ее работу по [Ctrl+C] с локального терминала.
Интересно оценить далеко идущие последствия этого «маленького» расширения стандартной POSIX-схемы работы с сигналами:
• На технике «сетевых сигналов» может быть построена целая система уведомлений сетевых составляющих компонент единой программной прикладной системы.
• Именно «уведомлений» (но не синхронизации с наследованием приоритетов, влияющей на общую систему диспетчеризации составляющих частей и т.п.): посылка сигнала является неблокирующей операцией (не требует ответа), а прием сигнала не сопровождается наследованием (или любым изменением) приоритетов.
• Такое «сигнальное» взаимодействие, записанное в формальной POSIX-семантике (но, по сути, осуществляющее механизмы, далеко выходящие за POSIX), может оказаться гораздо проще в записи и понимании, чем при использовании низкоуровневых механизмов обмена сообщениями (пульсами).
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
10.6. Сигналы POSIX
10.6. Сигналы POSIX API POSIX основан на API sigvec() из BSD 4.2 и 4.3. С небольшими изменениями этот API можно было отнести к возможностям API как V7, так и System V Release 3. POSIX сделал эти изменения и переименовал API sigaction(). Поскольку интерфейс sigvec() широко не использовался, мы не будем его описывать.
POSIX (BSD) API
POSIX (BSD) API Эта часть API наиболее полно соответствует API ОС UNIX, относящихся к ветви BSD (BSD, FreeBSD, NetBSD и другие).[5] Ее наименование можно было бы сузить до «BSD API», так как описанный далее набор API System V также регламентируется POSIX, но мы будем использовать именно термин «POSIX API», следуя
Сигналы
Сигналы В некотором смысле сигналы обеспечивают простейшую форму межпроцессного взаимодействия, позволяя уведомлять процесс или группу процессов о наступлении некоторого события. Мы уже рассмотрели в предыдущих главах сигналы с точки зрения пользователя и
Глава 10. Распространение сети за пределы вашего помещения
Глава 10. Распространение сети за пределы вашего помещения Первоначальной идеей спецификации 802.11b было обеспечение беспроводных подключений к сетям на ограниченной территории, например в офисах, домах и общественных учреждениях. Wi-Fi предполагалось сделать простым
Posix
Posix Название Posix образовано от «Portable Operating System Interface», что означает приблизительно «интерфейс переносимых операционных систем». Это не один стандарт, а целое семейство, разработанное Институтом инженеров по электротехнике и радиоэлектронике (Institute for Electrical and Electronics Engineers
Сигналы Posix: функции типа Async-Signal-Safe
Сигналы Posix: функции типа Async-Signal-Safe Недостаток пpoгрaммы из листинга 5.8 в том, что она вызывает mq_notify, mq_receive и printf из обработчика сигнала. Ни одну из этих функций вызывать оттуда не следует.Функции, которые могут быть вызваны из обработчика сигнала, относятся к группе,
5.7. Сигналы реального времени Posix
5.7. Сигналы реального времени Posix За прошедшие годы сигналы в Unix много раз претерпевали революционные изменения.1. Модель сигналов, предлагавшаяся в Unix Version 7 (1978), была ненадежной. Сигналы могли быть потеряны, и процессу было трудно отключить отдельные сигналы при
3.1.2. Выход за пределы диапазона при присваивании
3.1.2. Выход за пределы диапазона при присваивании Начнем с рассмотрения простого примера (листинг 3.1. проект Assignment1 на компакт-диске).Листинг 3.1. Неявное преобразование знакового числа в беззнаковое при присваиванииprocedure TForm1.Button1Click(Sender: TObject);var X: Byte; Y: ShortInt;begin Y:= -1; X:=
7.2.6.2. Сигналы
7.2.6.2. Сигналы Самый простой и грубый способ сообщения между двумя процессами на одной машине заключается в том, что один из них отправляет другому какой-либо сигнал (signal). Сигналы в операционной системе Unix представляют собой форму программного прерывания. Каждый сигнал
POSIX
POSIX В Linux и UNIX самый простой путь установления переменных окружения - добавить их определения в общесистемный профиль значений по умолчанию.Пользователь root также может:* выдать команды setenv() из командной строки wu командного скрипта;* для временного использования
POSIX
POSIX Linux, UNIX и другие платформы POSIX более предпочтительны, чем Windows, если требуется высокая безопасность. Технологии безопасности этих платформ являются продуманными и очень понятными в реализации. Безопасность файловой системы и надежный доступ присущи требованиям
26.2. Сигналы
26.2. Сигналы Сигнал относится к типу сообщений, которые пересылаются из системы для информирования команды или сценария о совершении какого?либо события. Обычно речь идет об ошибках, связанных с функционированием памяти, о проблемах с доступом к информации или об
Пределы полиморфизма
Пределы полиморфизма Неограниченный полиморфизм был бы несовместим со статическим понятием типа. Допустимость полиморфных операций определяется наследственностью.Все примеры полиморфных присваиваний, такие, как p := r и p := t, в качестве типа источника используют