MyBooks.club
Все категории

Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

На сайте mybooks.club вы можете бесплатно читать книги онлайн без регистрации, включая Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform. Жанр: Программное обеспечение издательство -,. Доступна полная версия книги с кратким содержанием для предварительного ознакомления, аннотацией (предисловием), рецензиями от других читателей и их экспертным мнением.
Кроме того, на сайте mybooks.club вы найдете множество новинок, которые стоит прочитать.

Название:
Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
Автор
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
16 сентябрь 2019
Количество просмотров:
350
Читать онлайн
Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform краткое содержание

Роб Кёртен - Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - описание и краткое содержание, автор Роб Кёртен, читайте бесплатно онлайн на сайте электронной библиотеки mybooks.club
Книга "Введение в QNX/Neutrino 2» откроет перед вами в мельчайших подробностях все секреты ОСРВ нового поколения от компании QNX Software Systems Ltd (QSSL) — QNX/Neutrino 2. Книга написана в непринужденной манере, легким для чтения и понимания стилем, и поможет любому, от начинающих программистов до опытных системотехников, получить необходимые начальные знания для проектирования надежных систем реального времени, от встраиваемых управляющих приложений до распределенных сетевых вычислительных системВ книге подробно описаны основные составляющие ОС QNX/Neutrino и их взаимосвязи. В частности, уделено особое внимание следующим темам:• обмен сообщениями: принципы функционирования и основы применения;• процессы и потоки: базовые концепции, предостережения и рекомендации;• таймеры: организация периодических событий в программах;• администраторы ресурсов: все, что относится к программированию драйверов устройств;• прерывания: рекомендации по эффективной обработке.В книге представлено множество проверенных примеров кода, подробных разъяснений и рисунков, которые помогут вам детально вникнуть в и излагаемый материал. Примеры кода и обновления к ним также можно найти на веб-сайте автора данной книги, www.parse.com.

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform читать онлайн бесплатно

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - читать книгу онлайн бесплатно, автор Роб Кёртен

Очевидным решением здесь является заключение lseek() и read() в пределы действия мутекса — когда первый поток захватит мутекс, мы будем знать, что он имеет эксклюзивный доступ к дескриптору. Второй поток должен будет ждать освобождения мутекса, прежде чем он сможет творить свое безобразие с позиционированием дескриптора.

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

Давайте взглянем на библиотечный вызов readblock() (из <unistd.h>):

int readblock(int fd, size_t blksize, unsigned block,

 int numblks, void *buff);

(Функция writeblock() описывается аналогично.)

Вы можете вообразить для функции readblock() довольно «простенькую» реализацию:

int readblock(int fd, size_t blksize, unsigned block,

 int numblks, void *buff) {

 lseek(fd, blksize * block, SEEK_SET); // Идем к блоку

 read(fd, buff, blksize * numblks);

}

Очевидно, что от такой реализации в многопоточной среде толку мало. Нам нужно будет как минимум добавить использование мутекса:

int readblock(int fd, size_t blksize, unsigned block,

 int numblks, void *buff) {

 pthread_mutex_lock(&block_mutex);

 lseek(fd, blksize * block, SEEK_SET); // Идем к блоку

 read(fd, buff, blksize * numblks);

 pthread_mutex_unlock(&block_mutex);

}

(Мы здесь предполагаем, что мутекс уже инициализирован.)

Этот код по-прежнему уязвим для «незащищенного» доступа — если некий поток вызовет lseek() на этом файловом дескрипторе без предварительной попытки захвата мутекса, вот у нас уже и ошибка.

Решение проблемы заключается в использовании составного сообщения, аналогично вышеописанному случаю с функцией chown(). В данном случае библиотечная реализация функции readblock() помещает обе операции — lseek() и read() — в единое сообщение и посылает это сообщение администратору ресурсов:

Составное сообщение для функции readblock().

Это работает, потому что передача сообщения является атомарной операцией. С точки зрения клиента, сообщение уходит либо целиком, либо не уходит вообще. Поэтому, вмешательство «незащищенной» функции lseek() становится несущественным — когда администратор ресурсов принимает сообщение с запросом readblock(), он делает это за один прием. (Очевидно, что в этом случае пострадает сама «незащищенная» lseek(), поскольку после отработки readblock() смещение на этом дескрипторе файла будет отличаться от того, которое она хотела установить.)

А как насчет самого администратора ресурсов? Как он обрабатывает операцию readblock() за один прием? Мы вскоре рассмотрим это, когда будем обсуждать операции, выполняемые для каждого компонента составных сообщений.

Структуры данных уровня POSIX

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

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

Структуры данных — общая схема.

Структурами данных являются:

iofunc_ocb_t — OCB (блок открытого контекста)

Содержит информацию по каждому дескриптору файла.

iofunc_attr_t — атрибутная запись

Содержит информацию по каждому устройству.

iofunc_mount_t — запись точки монтирования

Содержит информацию по каждой точке монтирования.

Когда мы обсуждали таблицы функций установления соединения и ввода/вывода, мы уже видели блоки открытого контекста и атрибутные записи — в таблицах функций ввода/вывода OCB был последним передаваемым параметром. Атрибутная запись передавалась как параметр handle (третий по счету) в функциях установления соединения. Запись точки монтирования обычно представляет собой глобальную структуру и привязывается к атрибутной записи «вручную» (в инициализационном коде, написанном вами для вашего администратора ресурса).

Структура блока открытого контекста (OCB) iofunc_ocb_t

Структура блока открытого контекста (OCB) содержит информацию по каждому дескриптору файла. Это означает, что когда клиент выполняет вызов open() и получает в ответ дескриптор файла (в противоположность коду ошибки), администратор ресурсов создает OCB и связывает его с данным клиентом. Этот OCB будет существовать до тех пор, пока клиент держит данный дескриптор файла открытым. В действительности, OCB и дескриптор файла — всегда согласованная пара. По каждому сообщению ввода/вывода от клиента библиотека администратора ресурсов автоматически ищет нужный OCB и вместе с сообщением передает его нужной функции из таблицы функций ввода/вывода. Это ответ на вопрос, зачем всем функциям ввода/вывода параметр ocb. В конце концов клиент закроет дескриптор файла (применив close()), что заставит администратор ресурса отвязать OCB от дескриптора файла и от клиента. Заметьте, что клиентская функция dup() просто увеличивает счетчик связей. В этом случае OCB отделяется от дескриптора файла и от клиента только тогда, когда значение счетчика связей достигнет нуля (то есть когда число вызовов close() будет соответствовать числу open() и dup()).

Как вы, наверное, догадываетесь, в OCB содержатся важные вещи по каждому открытию ресурса и по каждому дескриптору файла. Вот его содержание (взято из <sys/iofunc.h>):

typedef struct _iofunc_ocb {

 IOFUNC_ATTR_T *attr;

 int32_t       ioflag;

 CM НИЖЕ!!!    offset;

 uint16_t      sflag;

 uint16_t      flags;

} iofunc_ocb_t;

Проигнорируем пока комментарий относительно поля offset; мы вернемся к этому вопросу сразу же после данного обсуждения.

Поля структуры iofunc_ocb_t:

attr Указатель на атрибутную запись, связанную с данным блоком OCB. В функциях ввода/вывода вы будете встречать устоявшуюся идиому «ocb->attr»; она используется для получения доступа к элементам атрибутной записи. ioflag Режим открытия, то есть как был открыт ресурс (например, «только для чтения»). Заметьте, что поле ioflag содержит режим открытия (который был передан клиентской функции open()) плюс единица. Например, режим открытия O_RDONLY (значение 0) появится в поле ioflag, как значение, равное единице (1) (константа _READ из <stdio.h>). Это позволяет трактовать два младших бита поля ioflag как флаги разрешения чтения и записи (ioflag & _READ указывает на право доступа по чтению; ioflag & _WRITE — по записи). offset Текущее смещение lseek() в данном ресурсе. sflag Флаг разделяемого использования (см. <share.h>), используемый с клиентской функцией вызова sopen(). Возможны значения SH_COMPAT, SH_DENYRW, SH_DENYWR, SH_DENYRD, и SH_DENYN flags Системные флаги. В настоящее время поддерживаются два флага: IOFUNC_OCB_PRIVILEGED, указывающий на то, что этот OCB был создан в результате сообщения установления соединения от привилегированного процесса, и IOFUNC_OCB_MMAP, указывающий, используется ли этот OCB функцией mmap() на стороне клиента. На настоящий момент никаких других флагов не определено. Вы можете использовать биты, заданные в IOFUNC_OCB_FLAGS_PRIVATE, по своему собственному усмотрению.

Если вы хотите наряду со «стандартным» OCB сохранить какие-либо дополнительные данные, то будьте покойны — OCB можно «расширять». Мы обсудим это в разделе «Дополнительно».

Это странное поле offset

Поле offset, скажем так, как минимум любопытно. Посмотрите в <sys/iofunc.h>, как оно реализовано. В зависимости от того, какие у вас заданы флаги препроцессора, вы можете получить одну из шести (!) возможных раскладок поля offset. Но не беспокойтесь особо по поводу реализации — реально есть смысл рассматривать только два случая, в зависимости от того, хотите вы поддерживать 64-разрядные смещения или нет:


Роб Кёртен читать все книги автора по порядку

Роб Кёртен - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки mybooks.club.


Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform отзывы

Отзывы читателей о книге Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform, автор: Роб Кёртен. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.