Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
Шрифт:
Операционная система QNX/Neutrino может быть настроена для функционирования на различных аппаратных средствах без необходимости в лицензии на исходный код. Для этого необходимо предусмотреть в начальном загрузчике возможность обработки исходящих вызовов ядра. Механизм исходящих вызовов ядра позволяет разработчику добавлять в систему свой код, «знающий» о специфике оборудования — например, как опрашивать контроллер прерывания о том, какое прерывание произошло, или о том, как настроить таймер на регулярную генерацию прерываний, и т.п. Это очень подробно изложено в книге «Building Embedded Systems» («Построение
Абстрактный объект, через который сервер принимает сообщения. Это тот же самый объект, к которому клиент подключается, чтобы отправить сообщение серверу. При создании канала с помощью ChannelCreate возвращается идентификатор канала («channel ID», сокращенно «chid») — тот самый идентификатор канала, который назначается администратором ресурса каждой объявляемой им точке монтирования.
При карусельной диспетчеризации поток использует процессор до тех пор, пока либо не будет готов к работе поток с более высоким приоритетом, либо пока этот поток добровольно не освободит процессор, либо пока не истечет выделенный данному потоку квант времени. Если потоков с более высоким приоритетом нет, поток добровольно не освобождает процессор, и не существует других потоков с тем же самым приоритетом, поток будет выполняться вечно. Если удовлетворены все вышеизложенные условия, за исключением того, что становится готов к работе другой поток с таким же самым приоритетом, то предыдущий поток освободит процессор после того, как истечет выделенный ему квант времени — таким образом, другой поток будет иметь шанс на обслуживание. Сравните с диспетчеризацией FIFO.
Архитектура обмена сообщениями в QNX/Neutrino имеет клиент- серверную структуру. Клиент является тем, кто запрашивает услугу у определенного сервера. Обычно клиент запрашивает услуги, используя функции, ориентированные на работу со стандартными файловыми дескрипторами (например, lseek). Эти функции являются синхронными в том отношении, что вызов, сделанный клиентом, не возвращает ответ до тех пор, пока не будет завершена обработка запроса сервером. Любой поток может являться одновременно и клиентом, и сервером.
Объект, применяемый для упорядочения последовательности доступа потоков к ресурсу — так, чтобы к ресурсу, определяемому мутексом, в конкретный момент времени имел доступ только один поток. Например, используя мутекс всякий раз при обращении к некоторой переменной, вы гарантируете, что только один поток в данный момент времени имеет к ней доступ, там самым предотвращая гонки. См. также «атомарная операция».
Операционная система QNX/Neutrino имеет в своей основе модель обмена сообщениями, в которой все сервисы предоставляются синхронно, передачей сообщения от клиента к серверу и обратно. Клиент посылает сообщение серверу и блокируется. Сервер принимает сообщение от клиента, выполняет обработку запроса и затем отвечает на сообщение клиента, разблокируя его.
Подпрограмма, которой ядро передает управление (в привилегированном режиме) в результате аппаратного прерывания. Эта подпрограмма не имеет права выполнять системные вызовы и должна обеспечить возврат управления как можно скорее, поскольку ее приоритет реально выше, чем у любого потока в системе. Обработчики прерываний в QNX/ Neutrino могут возвращать структуру типа
Сервер отвечает на сообщение клиента, чтобы доставить клиенту результаты обработки его запроса.
Таймер с моментом истечения, определяемым как смещение от текущего момента времени, например, «через 5 минут». Сравните с абсолютным таймером.
Поток может передавать сообщения другому потоку. Для передачи сообщения применяется семейство функций MsgSend*; передающий сообщение поток блокируется до тех пор, пока принимающий поток не ответит на это сообщение (см. «обмен сообщениями»). Поток, который передает сообщение, считается клиентом.
Абсолютный или относительный таймер, который после истечения времени отсчета автоматически перезагружается, и продолжает делать так до явной отмены. Полезен для приема регулярных уведомлений.
Одиночный диспетчеризуемый поток управления. Реализация потоков обеспечивается непосредственно ядром Neutrino и соответствуют вызовам функций POSIX pthread*. Поток может быть синхронизирован с другими потоками (если таковые имеются) путем применения различных примитивов синхронизации, таких как мутексы, условные переменные, семафоры и т.д. Потоки подвергаются диспетчеризации по типу FIFO или RR (карусельного типа).
Поток может принять сообщение, вызвав функцию MsgReceive или MsgReceivev. Если сообщений нет, поток заблокируется в ожидании сообщения (см. «обмен сообщениями»). Поток, который принимает сообщение, считается сервером.
Недиспетчеризируемый объект, занимающий память и вмещающий в себя один или более потоков.
Ранее заблокированный поток будет разблокирован, когда условие, на основе которого он был заблокирован, будет удовлетворено. Например, поток может быть заблокирован в ожидании сообщения. Как только ему будет послано сообщение, он будет разблокирован.
Примитив синхронизации потоков, с которым ассоциируется счетчик. Потоки могут вызывать функцию sem_wait, и не будут при этом блокироваться, если в момент запроса счетчик имел ненулевое значение. Вызывая функцию sem_wait, поток уменьшает значение счетчика. Если поток вызывает sem_wait в тот момент, когда счетчик равен нулю, поток блокируется, пока некоторый другой поток не вызывает функцию sem_post, увеличивая тем самым значение счетчика. Сравните с барьером.