Системная архитектура QNX4 --------------------------------------------------------------- (С) QNX Software Systems Ltd., 1996 Автор: QNX Software Systems Ltd. Русское издание: SWD Software Ltd. WWW: http://www.swd.ru/qnx/support/literature/sysarch/ E-mail: books.qnx@swd.ru Date: 04 Mar 2002 ---------------------------------------------------------------
Впервые на русском языке книга о QNX. Роб Кертен "Введение в QNX/Neutrino 2". Аннотация, Заказ печатной версии(400 р.)

Системная архитектура QNX4

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

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

За информацией об установке и использовании QNX, обратитесь к книге Руководство пользователя ОС QNX

Системная архитектура содержит следующие главы:



 

Концепция QNX

Эта глава охватывает следующие темы:

Что такое QNX?

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

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

Операционная система QNX идеальна для приложений реального времени. Она обеспечивает все неотъемлемые составляющие системы реального времени: многозадачность, диспетчеризацию программ на основе приоритетов и быстрое переключение контекста.

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

QNX достигает своего уникального уровня производительности, модульности и простоты благодаря двум фундаментальным принципам:

Архитектура микроядра системы QNX

QNX состоит из небольшого ядра, координирующего работу взаимодействующих процессов. Как показано на рисунке, структура больше напоминает не иерархию, а команду, в которой несколько игроков одного уровня взаимодействуют между собой и со своим "защитником" - ядром.


fig: i/modules.gif


Микроядро системы QNX координирует работу системных менеджеров.


Настоящее ядро

Ядро - это "сердце" любой операционной системы. В некоторых операционных системах на него возлагается так много функций, что ядро, по сути, заменяет всю операционную систему!

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

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

Системные процессы

Все услуги операционной системы, за исключением тех, которые выполняются ядром, в QNX предоставляются через стандартные процессы. Типичная конфигурация QNX имеет следующие системные процессы:

Системные и пользовательские процессы

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

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

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

Предположим, что вы написали сервер базы данных. Как же должен быть классифицирован этот процесс?

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

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

Драйверы устройств

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

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

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

Связь между процессами (IPC)

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

Связь между процессами (Interprocess communication, сокращенно IPC) является ключом к разработке приложений как совокупности процессов, в которых каждый процесс выполняет отведенную ему часть общей задачи.

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

Передача сообщений

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

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

Передача сообщения позволяет не только обмениваться данными, но и является способом синхронизации выполнения нескольких процессов. Когда они посылают, получают или отвечают на сообщения, процессы претерпевают различные "изменения состояния", которые влияют на то, когда и как долго они могут выполняться. Зная состояния и приоритеты процессов, ядро организует их диспетчеризацию таким образом, чтобы максимально эффективно использовать ресурсы центрального процессора (ЦП).

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

QNX как сеть

В простейшем случае локальная сеть обеспечивает разделяемый доступ к файлам и периферийным устройствам для нескольких соединенных между собой компьютеров. QNX идет гораздо дальше этого простейшего представления и объединяет всю сеть в единый однородный набор ресурсов.

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

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

Модель единого компьютера

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

В условиях управления производством используются программируемые контроллеры и другие устройства ввода/вывода, а также комплексы программ, работающие в режиме реального времени, которым может потребоваться больше ресурсов, чем другим менее ответственным приложениям, таким как текстовый редактор. Сеть QNX достаточно "отзывчива", чтобы поддерживать одновременно оба этих типа приложений, QNX позволяет сфокусировать вычислительную мощность системы на производственном оборудовании (там, где это необходимо), в то же время, не жертвуя интерфейсом пользователя.

Гибкая поддержка сети

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


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

Каждому узлу QNX сети присваивается уникальный номер, который становится его идентификатором. Этот номер также единственный видимый признак того, функционирует QNX как сеть или как однопроцессорная операционная система.

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

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

Теперь давайте перейдем к более подробному рассмотрению структуры QNX.

Микроядро

Эта глава охватывает следующие темы:

Введение

Микроядро QNX отвечает за выполнение следующих функций:


fig: i/kernel.gif


Внутри микроядра QNX.


Связь между процессами

Микроядро QNX поддерживает три важнейшие формы связи между процессами: сообщения, прокси и сигналы.

IPC посредством сообщений

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

Примитивы передачи сообщений

Для непосредственной связи друг с другом взаимодействующие процессы используют следующие функции языка программирования Си:
Функция языка Си: Назначение:
Send()посылка сообщений
Receive()получение сообщений
Reply()ответ процессу, пославшему сообщение

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

Следует заметить, однако, что далеко не всегда возникает необходимость использовать функции Send(), Receive() и Reply() в явном виде. Библиотека функций языка Си в QNX построена на основе использования сообщений - в результате, когда процесс использует стандартные механизмы передачи данных (такие, как, например, программный канал - pipe), он косвенным образом использует передачу сообщений.


fig: i/messpass.gif


Процесс A посылает сообщение процессу B, который получает его, обрабатывает и посылает ответ


На рисунке изображена последовательность событий, имеющих место, когда два процесса, процесс A и процесс B, используют функции Send(), Receive() и Reply() для связи друг с другом:

  1. Процесс A посылает сообщение процессу B, вызвав функцию Send(), которая передает соответствующий запрос ядру. В этот момент времени процесс A переходит в SEND-блокированное состояние и остается в этом состоянии до тех пор, пока процесс B не вызовет функцию Receive() для получения сообщения.
  2. Процесс B вызывает Receive() и получает сообщение от процесса A. При этом состояние процесса A изменяется на REPLY-блокирован. Процесс B при вызове функции Receive() в данном случае не блокируется, т.к. к этому моменту его уже ожидало сообщение от процесса A.

    Заметьте, что если бы процесс B вызвал Receive() до того, как ему было послано сообщение, то он бы попал в состояние RECEIVE-блокирован до получения сообщения. В этом случае процесс-отправитель сообщения немедленно после посылки сообщения попал бы в состояние REPLY-блокирован.

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

Синхронизация процессов

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

Давайте снова рассмотрим приведенный выше рисунок. После того как процесс A вызвал функцию Send(), он не может продолжать выполнение до тех пор, пока не получит ответ на посланное сообщение. Это гарантирует, что выполняемая процессом B по запросу процесса A обработка данных будет завершена прежде, чем процесс A продолжит выполнение. Более того, после вызова процессом B запроса на получение данных Receive(), он не может продолжать выполнение до тех пор, пока не получит следующее сообщение.


Note: Более подробно диспетчеризация процессов в QNX рассматривается в разделе "Диспетчеризация процессов" далее в этой главе.

Блокированные состояния

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

Возможные блокированные состояния процессов приведены в следующей таблице:
Если процесс выдал: То процесс:
Запрос Send(), и отправленное им сообщение еще не получено процессом-получателем SEND-блокирован
Запрос Send(), и отправленное им сообщение получено процессом-получателем, но ответ еще не выдан REPLY-блокирован
Запрос Receive(), но еще не получил сообщение RECEIVE-блокирован


fig: i/states.gif


Изменение состояния процессов в типичном случае передачи сообщения.



Note: Для получения информации обо всех возможных состояниях процесса смотри главу "Менеджер процессов".

Использование Send(), Receive() и Reply()

Давайте теперь более подробно рассмотрим вызовы функций Send(), Receive() и Reply(). Воспользуемся рассмотренным выше примером передачи сообщения от процесса A к процессу B.

Функция Send()

Предположим, что процесс А выдает запрос на передачу сообщения процессу В. Это выполняется посредством вызова функции Send():

Send( pid, smsg, rmsg, smsg_len, rmsg_len );

При вызове функции Send() используются следующие аргументы:

pid
идентификатор процесса (process ID), которому предназначается сообщение (т.е. процесса B); этот идентификатор используется для обращения к процессу со стороны операционной системы и других процессов;
smsg
буфер сообщения (т.е. сообщение, подлежащее посылке)
rmsg
буфер ответа (будет содержать ответ от процесса B)
smsg_len
длина посылаемого сообщения в байтах
rmsg_len
максимальная длина ответа, который может принять процесс A, в байтах

Обратите внимание, что будет передано не более smsg_len байт и не более чем rmsg_len байт будет получено в качестве ответа - это гарантирует, что не произойдет случайного переполнения буферов.

Функция Receive()

Вызвав запрос Receive(), процесс B может получить сообщение, направленное ему процессом A:

pid = Receive( 0, msg, msg_len )

Вызов функции Receive() содержит следующие аргументы:

pid
идентификатор процесса, который послал сообщение (т.е. процесс A)
0
(ноль) означает, что процесс B желает принять сообщение от любого процесса
msg
буфер, куда будет помещено принимаемое сообщение
msg_len
максимальный размер данных, которые будут помещены в буфер приема, в байтах

Если значения аргументов smsg_len в вызове функции Send() и msg_len в вызове функции Receive() отличаются, друг от друга, то наименьшее из них определяет размер данных, которые будут переданы.

Функция Reply()

После успешного получения сообщения от процесса A, процесс B должен ответить процессу A, вызвав функцию Reply():

Reply( pid, reply, reply_len );

Вызов функции Reply() содержит следующие аргументы:

pid
идентификатор процесса, которому предназначается ответ (т.е. процесс A)
reply
буфер, содержащий ответ
reply_len
длина данных, передаваемых в качестве ответа, в байтах

Если значения аргументов reply_len при вызове функции Reply() и rmsg_len при вызове функции Send() отличаются друг от друга, то наименьшее из них определяет размер передаваемых данных.

Reply-управляемый обмен сообщениями

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

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

Дополнительные сведения

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


fig: i/blocproc.gif


Сервер получил сообщение от клиента A и клиента B (но еще не ответил им). Сообщения от клиентов C, D, E еще не получены.


Дополнительные возможности

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

Условный прием сообщений

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

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


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

Чтение или запись части сообщения

Иногда желательно читать или записывать сообщения по частям с тем, чтобы использовать уже выделенный для сообщения буфер вместо выделения отдельного рабочего буфера.

Например, менеджер ввода/вывода может принимать данные в виде сообщений, которые состоят из заголовка фиксированной длины и следующих за ним данных переменной длины. В заголовке указывается размер данных (от 0 до 64 Кбайт). В этом случае менеджер ввода/вывода может сначала принять только заголовок сообщения, а затем использовать функцию Readmsg() для чтения данных переменной длины непосредственно в соответствующий буфер вывода. Если размер данных превышает размер буфера, то менеджер может неоднократно вызывать функцию Readmsg() по мере освобождения буфера вывода. Аналогичным образом, функция Writemsg() может быть использована для поэтапного копирования данных в выделенный для ответного сообщения буфер непосредственно в теле процесса, пославшего сообщение, уменьшая, таким образом, потребность менеджера ввода/вывода в выделении внутренних буферов.

Составные сообщения

До сих пор мы рассматривали сообщения как непрерывную последовательность байт. Однако сообщения часто состоят из двух или более отдельных частей. Например, сообщение может иметь заголовок фиксированной длины, за которым следуют данные переменной длины. Для того чтобы избежать копирования частей такого сообщения во временные промежуточные буферы при передаче или приеме, может быть использовано составное сообщение, состоящее из двух или более отдельных буферов сообщений. Именно благодаря этой возможности менеджеры ввода/вывода QNX, такие как Dev и Fsys, достигают своей высокой производительности.

Следующие функции позволяют обрабатывать составные сообщения:


fig: i/multimsg.gif


Составные сообщения могут быть описаны с помощьюqqq0 специальной mx структуры. Микроядро объединяет части такого сообщения в единый непрерывный поток данных.


Зарезервированные коды сообщений

QNX начинает все сообщения с 16-ти битного слова, называемого кодом сообщения. Заметим, однако, что это не является обязательным для вас требованием при написании собственных программ. QNX использует коды сообщений в следующих диапазонах:
Зарезервированный диапазон: Описание:
0x0000 - 0x00FF Сообщения Менеджера процессов
0x0100 - 0x01FF Сообщения ввода/вывода (общие для всех серверов ввода/вывода)
0x0200 - 0x02FF Сообщения Менеджера файловой системы
0x0300 - 0x03FF Сообщения Менеджера устройств
0x0400 - 0x04FF Сообщения Менеджера сети
0x0500 - 0x0FFF Зарезервированы для будущих системных процессов QNX

IPC посредством прокси

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

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

Вот некоторые примеры использования прокси:

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

Прокси может быть "запущено" неоднократно - каждый раз при этом оно посылает сообщение. Прокси может накапливать очередь длиной до 65535 сообщений.


fig: i/prxytrig.gif


Процесс-клиент запускает прокси 3 раза, в результате чего сервер получает 3 "консервированных" сообщения от прокси.


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

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

QNX поддерживает большой набор сигналов, соответствующих стандарту POSIX, кроме того, сигналы, исторически присущие некоторым UNIX-системам, и ряд сигналов, уникальных для QNX.

Как породить сигнал

Считается, что сигнал доставлен процессу тогда, когда выполняется определенное в процессе для данного сигнала действие. Процесс может посылать сигнал самому себе.
Если вы хотите: Используйте:
Породить сигнал из командной строки Утилиты: kill и slay
Породить сигнал внутри процесса Функции Си: kill() и raise()

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

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

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

Перечень сигналов
Сигнал: Описание:
SIGABRT Сигнал ненормального завершения, порождается функцией abort().
SIGALRM Сигнал тайм-аута, порождается функцией alarm().
SIGBUS Указывает на ошибку контроля четности оперативной памяти (особая для QNX интерпретация). Если во время выполнения обработчика данного сигнала произойдет вторая такая ошибка, то процесс будет завершен.
SIGCHLD Завершение порожденного процесса. Действие по умолчанию - игнорировать сигнал.
SIGCONT Если процесс в состоянии HELD, то продолжить выполнение. Действие по умолчанию - игнорировать сигнал, если процесс не в состоянии HELD.
SIGDEV Генерируется, когда в Менеджере устройств происходит важное и запрошенное событие.
SIGFPE Ошибочная арифметическая операция (целочисленная или с плавающей запятой), например, деление на ноль или операция, вызвавшая переполнение. Если во время выполнения обработчика данного сигнала произойдет вторая такая ошибка, то процесс будет завершен.
SIGHUP Гибель процесса, который был ведущим сеанса, или зависание управляющего терминала.
SIGILL Обнаружение недопустимой аппаратной команды. Если во время выполнения обработчика данного сигнала произойдет вторая такая ошибка, то процесс будет завершен.
SIGINT Интерактивный сигнал "внимание" (Break)
SIGKILL Сигнал завершения - должен быть использован только в экстренных ситуациях. Этот сигнал не может быть "пойман" или игнорирован. Сервер может защитить себя от этого сигнала посредством функции языка Си qnx_pflags(). Для этого сервер должен иметь статус привилегированного пользователя.
SIGPIPE Попытка записи в программный канал, который не открыт для чтения.
SIGPWR Перезапуск компьютера в результате нажатия Ctrl-Alt-Shift-Del или вызова утилиты shutdown.
SIGQUIT Интерактивный сигнал завершения.
SIGSEGV Обнаружение недопустимой ссылки на оперативную память. Если во время выполнения обработчика данного сигнала произойдет вторая такая ошибка, то процесс будет завершен.
SIGSTOP