19. Операции над семафорами
Семафор – защищенная переменная, значение которой можно опрашивать и изменять только при помощи специальных операций p() и v() (проверка и увеличение соотв.); начальное значение – число единиц ресурсов.
P(s)-> s=s-1
V(s)-> s=s+1
Алгоритм реализации p и v.
P: При вызове ф-ция проверяет значение s: если s>0, то s=s-1, иначе текущую задачу ставим в конец списка блокированных.
V: Выполняется проверка
: да – S=S+1
Нет - S=S+1, взять первую задачу из списка блокированных и удалить ее оттуда, пометив как готовую.
Операции, определенные над семафорами с учетом вышеизложенного:
Семафор может быть инициализирован неотрицательным значением. Операция P уменьшает значение семафора. Если это значение становится отрицательным, процесс, выполняющий операцию Р, блокируется. Операция V увеличивает значение семафора. Если это значение не положительно, то заблокированный операцией Р процесс деблокируется.20. Синхронизация процессов при помощи семафоров
В памяти находятся две неотрицательные целые переменные, называемые семафорами. Операционная система располагает двумя командами уровня 3 для действий над этими переменными: UP и DOWN (V и Р соотв.). UP прибавляет 1 к семафору, a DOWN вычитает из него 1.
Важным свойством семафорных команд является то, что, если какой-то процесс инициировал команду обработки семафора, ни один другой процесс не может обратиться к этому семафору до тех пор, пока первый процесс или закончит выполнение семафорной команды, или будет остановлен при попытке выполнить команду DOWN над семафором, имеющим нулевое значение.
Пример1. Имеются два семафора: AVAILABLE, начальное значение которого равно 100 (объем буфера), и FILLED, начальное значение которого есть 0. Изготовитель начинает работу с оператора Р1, а потребитель - с оператора С1. Выполнение команды DOWN над семафором FILLED сразу же останавливает процесс потребителя. Изготовитель, отыскав первое простое число, выполняет команду DOWN над семафором AVAILABLE, присваивая ему значение 99. Используя оператор Р5, изготовитель выполняет команду UP над FILLED, делая его равным 1. Тем самым снимается запрет с работы потребителя, который может теперь завершить выполнение своей команды DOWN. С этого момента FILLED равен 0, и оба процесса имеют место. В некоторый момент времени IN=22, OUT=21, изготовитель выполняет Р1, а потребитель - С5. Потребитель заканчивает свои действия и переходит к С1, т е. выполнение команды DOWN над семафором, который имел значение 1 до этой команды и становится равным 0 после ее применения. Затем он берет из буфера последнее число и выполняет UP над AVAILABLE, присваивая ему значение 100. Выведя на печать число, потребитель переходит к С1. Как раз перед тем, как потребитель намеревается выполнить команду DOWN, изготовитель находит очередное простое число и быстро выполняет один за другим операторы Р2, РЗ и Р4 (смахивает на фортран, хотя я не уверен, тем не менее переделать, скажем под Си, совсем не сложно)
PRODUCER: PROCEDURE;
DECLARE (AVAILABLE, FILLED, IN, OUT, BUFFER(1:100)) FIXED BINARY EXTERNAL, PRIME FIXED BINARY INITIAL(l);
DO WHILE (PRIME < 1000000);
P1: CALL COMPUTE_NEXT_PRIME(PRIME);
P2: CALL DOWN(AVAILABLE);
P3: BUFFER(IN) = PRIME;
P4: IN * IN + 1; IF IN = 101 THEN IN * 1;
P5: CALL UP(FILLED);
END;
END PRODUCER;
CONSUMER: PROCEDURE;
DECLARE (AVAILABLE, FILLED, IN, OUT, BUFFER(1:100)) FIXED BINARY EXTERNAL, EMIRP FIXED BINARY INITIAL(l);
DO WHILE (EMIRP < 1000000);
Cl: CALL DOWN(FILLED);
C2: EMIRP = BUFFER(OUT);
C3: OUT = OUT + 1; IF OUT = 101 THEN OUT = 1;
C4: CALL UP(AVAILABLE);
C5: PUT SKIP LIST(EMIRP);
END;
END CONSUMER;
Сейчас FILLED=0, причем изготовитель собирается применить к нему команду UP, а потребитель - команду DOWN. Если первым выполнит свою команду потребитель, его работа будет остановлена до тех пор, пока изготовитель не снимет с нее запрета (выполнив команду UP). В противном случае, если первым выполнит свою команду изготовитель, семафор примет значение 1 и потребителю не придется останавливаться. В обоих случаях нет потери сигналов побудки.
Пример 2.(упрощенный пример 1)
begin
Parbegin
Процесс_Х:
begin
While (true) do
begin
Call (Cемафор. Р);
{Критический участок Процесса_Х};
Call(Семафор.V);
{Оставшиеся операторы Процесса_Х}
end
end;
Процесс_Y;
begin
While (true) do
begin
Call (Cемафор. Р);
{Критический участок Процесс_Y};
Call(Семафор.V);
{Оставшиеся операторы Процесса_Y}
end
end
Parend
end.
21. Кольцевые буферы с семафорами
Для реализации операций записи и чтения из буфера удобно использовать кольцевой буфер (см. рис. 5.6). При этом вводятся два указателя: iw – для записи, ir – для чтения. Указатель iw определяет пустую ячейку в буфере, куда процесс-производитель должен поместить сообщение. Указатель ir определяет ячейку в буфере, откуда процесс-потребитель должен считать сообщение. Условие iw = ir указывает, что буфер пуст. Для реализации кольцевого буфера можно использовать линейный буфер емкостью N. При этом для сдвига указателей следует использовать сложение с единицей по модулю N: iw = (iw + 1)mod N; ir = (ir + 1)mod N.

22.Ограничения, налагаемые на использования семафоров
использование не обязательно(нет механизма контроля семафоров – при программировании возможны ошибки, связанные с неформализованностью механизма). проверить значение семафора можно только с использованием блокирующего вызова Р(). при вызове операции Р() нельзя задать список семафоров. время блокировки не ограничено. семафор не является средством, с помощью которого один процесс может контролировать другой без участия с его стороны. семафор не может использоваться для обмена данными.23. Тупики и бесконечное откладывание
Тупик – состояние процесса, в котором он ожидает наступления события, которое никогда не произойдет.
Зависание – ситуация, когда один или более процессов оказываются в состоянии тупика.
Тупики могут быть вызваны:
ожидание несуществующего события ожидание ненаступаемого события бесконечное откладывание (ситуация, при которой предоставление процессора некоторому процессу будет откладываться на неопределенно долгий срок, в то время как система будет уделять внимание другим процессам.)Бесконечное откладывание процесса может происходить из-за «дискриминационной» политики планировщика ресурсов системы. Когда ресурсы распределяются по приоритетному принципу, может случиться, что данный процесс будет бесконечно долго ожидать выделения нужного ему ресурса, поскольку будут постоянно приходить процессы с более высокими приоритетами.
Модели для изучения тупиков:
на основе сетей Петри модель Холта модель пр-ва состояния24. Условие возникновения тупика
условие взаимоисключения (монопольный доступ к ресурсам) условие ожидания (после получения одного ресурса процесс может ждать бесконечно долго всех остальных ресурсов) условие отсутствия перераспределения (система не может отобрать выделенные ресурсы) условие кругового ожидания
61. Службы синхронизации QNX
Название | Межзадачная поддержка | Сетевая поддержка |
Мютекс | + | - |
Условная переменная | + | - |
Ждущая блокировка[1] | - | - |
Барьер | - | - |
Блокировка чтения/записи | + | - |
Семафор | + | +[2] |
FIFO-планирование | + | - |
Сообщения | + | + |
Атомарные операции | + | - |
Все примитивы синхронизации реализуются ядром, кроме барьеров, ждущих блокировок, блокировок чт./зап., которые основаны на мютексах и условных переменных, и атомарных операций, которые либо выполняются процессором, либо эмулируются ядром.
Усл. переменная используется для проверки секции по условию pthread_cond_wait/signal/broadcast/timeout().
QNX предоставляет упрощенный вариант использования условной переменной, для блокирования (остановки) потока, предоставляя интерфейс т. н. ждущей блокировки (sleepon). Для использования этого механизма не нужно явно создавать никаких объектов синхронизации, это делает ОС. Внешне ждущие блокировки выглядят как набор функций ожидания и освобождения, при этом последовательность действий аналогична использованию мютексов и условных переменных. За этим интерфейсом на самом деле скрывается один мютекс и несколько дополнительных условных переменных. Использование функций ожидания должно проходить внутри участка кода, отмеченного вызовами блокирования и разблокирования ассоциированного с ждущей блокировкой мютекса. Одним из основных недостатков ждущей блокировки является то, что для всех потоков и всех ключей ожидания используется один общий мютекс. ОС не может отслеживать взаимные блокировки потоков при использовании ждущих блокировок.
Барьер – механизм синхронизации, позволяющий координировать работу нескольких потоков. По умолчанию атрибуты барьера запрещают доступ к элементу синхронизации из других процессов.
int pthread_barrierattr_init( pthread_barrierattr_t * attr );
int pthread_barrierattr_destroy( pthread_barrierattr_t * attr );
Функция инициализации и разрушения возвращает следующие значения: EOK – успешное выполнение; ENOMEM – недостаточно памяти для инициализации атрибутов барьера; EINVAL – передан неверный объект атрибутов барьера attr; EBUSY – попытка инициализации инициализированного барьера/в настоящее время есть потоки блокированные не барьере; EAGAIN – Системе не хватает ресурсов для инициализации барьера; EFAULT – Сбой произошел при обращении ядра к аргументам.
FIFO-планирование применяется в системах без SMP для синхронизации потоков с одинаковым приоритетом. Нет необходимости явного вызова процедуры синхронизации.
Атомарные операции хранятся в заголовочном файле <atomic. h> и служат для незапрещения прерываний.
62. Send и Reply-управляемая передача сообщений
Способ передачи сообщений называется Send-управляемым, если процесс, требующий обслуживания, инициирует работу, посылая сообщение, а обслуживающий процесс завершает работу, выдавая ответ на принятое сообщение.
Reply-управляемый способ передачи сообщений - способ, при котором работа инициируется функцией MsgReply(). В соответствии с этим способом "рабочий" процесс посылает сообщение обслуживающему процессу, указывая на то, что он готов к работе. Обслуживающий процесс фиксирует, что "рабочий" процесс послал ему сообщение, но не отвечает ему немедленно. Через некоторое время обслуживающий процесс может ответить "рабочему" процессу. "Рабочий" процесс выполняет свою работу, а затем, завершив ее, посылает обслуживающему процессу сообщение, содержащее результаты.
63. Передача данных и уведомления, импульсы
Хз. Не нашел=)
64. Условный прием сообщений
Обычно для приема сообщения используется функция Receive(). Этот способ приема сообщений в большинстве случаев является наиболее предпочтительным.
Однако, иногда процессу требуется предварительно "знать", было ли ему послано сообщение, чтобы не ожидать поступления сообщения в RECEIVE-блокированном состоянии. Например, процессу требуется обслуживать несколько высокоскоростных устройств, не способных генерировать прерывания, и кроме того, процесс должен отвечать на сообщения, поступающие от других процессов. В этом случае используется функция Creceive(), которая считывает сообщение, если оно становится доступным, или немедленно возвращает управление процессу, если нет ни одного отправленного сообщения.
По возможности следует избегать использования функции Creceive(), так как она позволяет процессу непрерывно загружать процессор на соответствующем приоритетном уровне.
65. Чтение сообщения по частям и приём составных сообщений
Как правило, сообщения состоят из нескольких дискретных частей. Например, сообщение может иметь заголовок фиксированной длины, за которым следуют данные переменной длины. Для того, чтобы части сообщения эффективно передавались и принимались без копирования во временный рабочий буфер, составное сообщение может формироваться в нескольких раздельных буферах. Этот метод позволяет администраторам ввода/вывода системы QNX Dev и Fsys, обеспечивать высокую производительность.
Для работы с составными сообщениями используются следующие функции:
- Creceivemx() Readmsgmx() Receivemx() Replymx() Sendmx() Writemsgmx()

Cоставное сообщение может быть описано с помощью управляющей структуры mx. Ядро собирает части сообщения в единый поток данных.
Чтение или запись части сообщения
В некоторых случаях предпочтительнее считывать или записывать только часть сообщения для того, чтобы использовать буфер, уже выделенный для сообщения, и не заводить рабочий буфер. Например, администратор ввода/вывода может принимать для записи сообщения, состоящие из заголовка фиксированной длины и переменного количества данных. Заголовок содержит значение количества байт данных (от 0 до 64 Кбайт). Администратор ввода/вывода может принимать сначала только заголовок, а затем, используя функцию Readmsg(), считывать данные переменной длины в соответствующий буфер. Если количество посылаемых данных превышает размер буфера, администратор ввода/вывода может вызывать функцию Readmsg() несколько раз, передавая данные по мере освобождения буфера. Аналогично, функцию Writemsg() можно использовать для сбора и копирования данных в буфер отправителя по мере его освобождения, снижая таким образом требования к размеру внутреннего буфера администратора ввода/вывода.
66. PROXY
Proxy представляет собой форму неблокирующей передачи сообщений, специально предназначенную для оповещения о событиях, при которых процесс-отправитель не нуждается во взаимодействии с процессом-получателем. Единственной функцией proxy является посылка фиксированного сообщения процессу, создавшему proxy. Proxy работают по всей сети.
Благодаря использованию proxy, процесс или обработчик прерываний может послать сообщение другому процессу, не блокируясь и не ожидая ответа. Ниже приведены некоторые примеры использования proxy:
- процесс оповещает другой процесс о наступлении некоторого события, не желая при этом оставаться SEND-блокированным до тех пор, пока получатель не выдаст Receive() и Reply(); процесс посылает данные другому процессу, но не требует ни ответа, ни другого подтверждения о том, что получатель принял сообщение; обработчик прерываний оповещает процесс о том, что некоторые данные доступны для обработки.
Proxy создаются с помощью функции qnx_proxy_attach(). Любой процесс или обработчик прерываний, которому известен идентификатор proxy, может воспользоваться функцией Trigger() для того, чтобы выдать заранее определенное сообщение. Запросами Trigger() управляет ядро.
Процесс proxy может быть запущен несколько раз: выдача сообщения происходит каждый раз при его запуске. Процесс proxy может накопить в очереди для выдачи до 65535 сообщений.

67. Сигналы (момент приёма, блокировка сигналов, сигналы и сообщения)
Сигнал – программный механизм, аналогичный прерыванию (без использования приоритетов), который информирует процесс о наступлении асинхронного события.
Сообщение – некий малый объем данных, синхронно передаваемый от процесса к процессу.
Доставка сигнала выполняется путем обновления поля в таблице процесса, которому послан данный сигнал. Т. к. каждый сигнал соответствует отдельному биту, сигналы одного типа не могут накапливаться в виде очереди.
В зависимости от того, каким образом был определен способ обработки сигнала, возможны три варианта его приема:
Если процессу не предписано выполнять каких-либо специальных действия по обработке сигнала, то по умолчанию поступление сигнала прекращает выполнение процесса; Процесс может проигнорировать сигнал. В этом случае выдача сигнала не влияет на работу процесса (обратите внимание на то, что сигналы SIGCONT, SIGKILL и SIGSTOP не могут быть проигнорированы при обычных условиях); Процесс может иметь обработчик сигнала, которому передается управление при поступлении сигнала. В этом случае говорят, что процесс может "ловить" сигнал. Фактически такой процесс выполняет обработку программного прерывания. Данные с сигналом не передаются.Блокировка сигналов
Иногда может потребоваться временно задержать выдачу сигнала, не изменяя при этом способа его обработки. В системе QNX имеется набор функций, которые позволяют блокировать выдачу сигналов. После разблокировки сигнал выдается программе.
Во время работы обработчика сигналов QNX автоматически блокирует обрабатываемый сигнал. Это означает, что не требуется организовывать вложенные вызовы обработчика сигналов. Каждый вызов обработчика сигналов непрерываем остальными сигналами данного типа. При нормальном возврате управления от обработчика, сигнал автоматически разблокируется.
Сигналы и сообщения
Существует важная взаимосвязь между сигналами и сообщениями. Если при генерации сигнала ваш процесс окажется SEND-блокированным или RECEIVE-блокированным (причем имеется обработчик сигналов), то будут выполняться следующие действия:
процесс разблокировывается; выполняется обработка сигнала; функции Send() или Receive() возвращают управление с кодом ошибки.Если процесс был SEND-блокированным, то проблемы не возникает, так как получатель не получит сообщение. Но если процесс был REPLY-блокированным, то неизвестно, было обработано отправленное сообщение или нет, а следовательно неизвестно, нужно ли еще раз выдавать Send().
Процесс, выполняющий функции сервера (т. е. принимающий сообщения), может запрашивать уведомления о том, когда обслуживаемый процесс выдаст сигнал, находясь в REPLY-блокированном состоянии. В этом случае обслуживаемый процесс становится SIGNAL-блокированным с задержанным сигналом, и обслуживающий процесс принимает специальное сообщение, описывающее тип сигнала. Обслуживающий процесс может выбрать одно из следующих действий:
нормально завершить первоначальный запрос: отправитель будет уведомлен о том, что сообщение было обработано надлежащим образом; освободить все закрепленные ресурсы и возвратить управление с кодом ошибки, указывающим на то, что процесс был разблокирован сигналом: отправитель получит чистый код ошибки.Когда обслуживающий процесс сообщает другому процессу, что он SIGNAL-блокирован, сигнал выдается немедленно после возврата управления функцией Send().
68. Межпроцессное взаимодействие в сети, виртуальные каналы и процессы
Если 2 процесса обмениваются сообщениями, то между ними устанавливается канал. Канал можно представить как путь или способ, с помощью которого происходит передача сообщений. Для удобства каналы считаются однонаправленными.
2 типа каналов: именованные и неименованные. Совместно использовать НК могут только связанные друг с другом процессы; не связанные друг с другом процессы могут совместно использовать только ИК.
Виртуальные каналы (ВК) способствуют эффективному использованию ресурсов во всей сети QNX по нескольким причинам:
при создании виртуального канала имеется возможность задать работу с сообщениями определенной длины: это означает, что вы можете распределить ресурсы для обработки сообщения. Тем не менее, если потребуется послать сообщение, длина которого превышает максимально заданную, виртуальный канал автоматически изменит установленный максимальный размер буфера в соответствии с длиной передаваемого сообщения; если два процесса, находящиеся на разных узлах, взаимодействуют между собой более, чем через один виртуальный канал, виртуальные каналы разделяются во времени, так как между процессами существует только один реальный виртуальный канал. Эта ситуация часто возникает, когда процесс обращается к нескольким файлам удаленной файловой системы; если процесс подключается к существующему разделенному виртуальному каналу и запрашивает размер буфера больший, чем тот, который используется в данное время, размер буфера автоматически увеличивается; когда процесс завершается, все связанные с ним виртуальные каналы освобождаются.Виртуальные процессы
Процесс-отправитель отвечает за установку виртуального канала между собой и процессом, с которым устанавливается связь. Для этого процесс-отправитель обычно вызывает функцию qnx_vc_attach(). При этом, кроме создания виртуального канала, на каждом конце канала создается виртуальный процесс с идентификатором - VID. Для каждого процесса на обоих концах виртуального канала VID представляет собой идентификатор удаленного процесса, с которым устанавливается связь. Процессы связываются друг с другом посредством VID.
Каждый VID обеспечивает соединение, которое содержит следующую информацию:
- локальный pid; удаленный pid; удаленный nid (идентификатор узла); удаленный vid.

Связь по сети осуществляется посредством виртуальных каналов. Когда процесс PID1 посылает сообщение VID2 запрос send проходит по виртуальному каналу, в результате чего PID2 получает сообщение от VID1.
69. Алгоритмы планирования
См. п. 41.
70. Защита от инверсии приоритетов
Инверсия приоритетов возникает, когда два потока, высоко приоритетный (В) и низкоприоритетный (Н) разделяют некий общий ресурс (Р). Предположим, также что в системе присутствует третий поток, приоритет которого находится между приоритетами В и Н. Назовем его средним (С). Если поток В переходит в состояние готовности когда активен поток Н и Н заблокировал ресурс Р, то поток В вытеснит поток Н и Р останется заблокирован. Когда В понадобится ресурс Р, то он сам перейдет в заблокированное состояние. Если в состоянии готовности находится только поток Н, то ничего страшного не произойдет, Н освободит заблокированный ресурс и будет вытеснен потоком В. Но если на момент блокирования потока В, в состоянии готовности находится поток С, приоритет которого выше чем у Н, то активным станет именно он, а Н опять будет вытеснен, и получит управление только после того, как С закончит свою работу. Подобная задержка вполне может привести к тому, что критическое время обслуживания потока В будет пропущено. Если В это поток жесткого реального времени, то подобная ситуация недопустима.
Какие же механизмы защиты от этой проблемы используют разработчики операционных систем реального времени? Наиболее широко распространенный и проверенный механизм – это наследование приоритетов.
Механизм наследования приоритетов, к сожалению, не всегда может решить проблемы, связанные с блокирование высокоприоритетного потока на заблокированном ресурсе. В случае, когда несколько средне– и низко–приоритетных потоков разделяют некоторые ресурсы с высокоприоритетным потоком возможна ситуация, когда высокоприоритетному потоку придется слишком долго ждать пока каждый из младших потоков не освободит свой ресурс и критический срок обслуживания будет потерян. Однако такие ситуации (разделения ресурсов высокоприоритетного потока) должны отслеживаться разработчиками прикладной системы. В принципе наследование приоритетов является наиболее распространенным механизмом защиты от проблемы инверсии приоритетов.
Другой, несколько менее распространенный метод, называется Протокол Предельного Приоритета (Priority Ceiling Protocol) [6]. Метод этот заключается в добавлении к стандартным свойствам объектов синхронизации параметра, определяемого максимальным приоритетом потока, которые к этому объекту обращаются. Если этот параметр установлен, то приоритет любого потока, обращающегося к этому объекту синхронизации, будет увеличен до указанного уровня, и, таким образом, не сможет быть вытеснен никаким потоком, который может нуждаться в заблокированном им ресурсе. После разблокирования ресурса, приоритет потока понижается до начального уровня. Таким образом, получается нечто вроде предварительного наследования приоритетов. Однако этот метод имеет ряд серьезных недостатков. В первую очередь, на разработчика ложиться работа по «обучению» объектов синхронизации их уровню приоритетов. Во вторых, возможны задержки в запуске высокоприоритетных потоков на время отработки низкоприоритетных потоков. В целом максимально эффективно этот механизм может быть использован в случае, когда имеется один поток жесткого реального времени и несколько менее приоритетных потоков, разделяющих с ним ресурсы.
71. Задержки и их расчет: задержка обработки прерывания, задержка планирования
Задержка прерывания - это интервал времени между приемом аппаратного прерывания и началом выполнения первой команды обработчика данного прерывания. В системе QNX все прерывания открыты все время, поэтому задержка прерывания обычно незначительна. Но некоторые критические программы требуют, чтобы на время их выполнения прерывания были закрыты. Максимальное время закрытия прерывания обычно определяет худший случай задержки прерывания; следует отметить, что в системе QNX это время очень мало.
На рисунке представлена диаграмма обработки аппаратного прерывания соответствующим обработчиком прерываний. Обработчик прерываний либо просто возвращает управление процессу, либо возвращает управление и вызывает "срабатывание" proxy.

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

72. Диагностическая версия микроядра (далее дмкя – прим. автора)
Дмкя генерирует трассировочные события по различным системным операциям. Эти события сохраняются в наборе циклически связанных буферов. По заполнению буфера дмкя отправляют уведомление утилите сбора данных Утилита копирует данные из буфера в соотв. устройство вывода Спец. инструмент выполняет операции фильтрации, интерпретации данных для пользователя.Диагностическая версия микроядра может отслеживать и протоколировать каждое системное событие, включая вызовы ядра, прерывания, сообщения, смену состояний потоков и планирование. Фактически, она представляет собой логический анализатор для всей системы: если что-то сработает не так, ядро поможет выяснить, когда произошло событие, какие программные модули были в нем задействованы, что они делали, и, самое главное, как интерпретировать это событие.
Будучи альтернативой стандартному микроядру QNX Neutrino, диагностическая версия абсолютно аналогична ему по функциональности. Более того, ее можно использовать в системах, находящихся в эксплуатации, поскольку она лишь немногим медленнее обычного микроядра. Влияние на производительность системы проявляется только в процессе трассировки событий, но и здесь можно свести это влияние к минимуму, производя динамическое протоколирование и фильтруя информацию по уровням важности.

73. Особенности работы QNX в SMP-системах
По заявлениям QSSL, бета тестирование SMP Neutrino продемонстрировало близкий к линейному (!) рост производительности при добавлении дополнительных процессоров (до 8), при автоматической балансировке нагрузки. Скептики скажут, что это невозможно, но они всегда это говорят J. Многое в QNX и Neutrino "невозможно". Кроме того, реализация SMP Neutrino допускает ручное распределение процессов между процессорами, что позволит добиться еще большей эффективности в контролируемой среде исполнения.
[1] Только внутри процессов
[2] Только для именованных семафоров


