Читаем QNX/UNIX полностью

где 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 raqc

• После чего, выполнив ряд операций в запущенной программе, прекращаем ее работу по [Ctrl+C] с локального терминала.

Интересно оценить далеко идущие последствия этого «маленького» расширения стандартной POSIX-схемы работы с сигналами:

• На технике «сетевых сигналов» может быть построена целая система уведомлений сетевых составляющих компонент единой программной прикладной системы.

• Именно «уведомлений» (но не синхронизации с наследованием приоритетов, влияющей на общую систему диспетчеризации составляющих частей и т.п.): посылка сигнала является неблокирующей операцией (не требует ответа), а прием сигнала не сопровождается наследованием (или любым изменением) приоритетов.

• Такое «сигнальное» взаимодействие, записанное в формальной POSIX-семантике (но, по сути, осуществляющее механизмы, далеко выходящие за POSIX), может оказаться гораздо проще в записи и понимании, чем при использовании низкоуровневых механизмов обмена сообщениями (пульсами).

<p>4. Примитивы синхронизации</p>
Перейти на страницу:

Все книги серии High tech

Нет соединения с сервером, попробуйте зайти чуть позже