- •Министерство образования и науки Украины
- •1. Определение системам реального времени
- •1.1. Основные понятия
- •1.2. Срв
- •1.3. Классификация срв
- •1.4. Структура срв
- •Основные требования к срв и их особенности
- •1.4.1. Ос
- •1.4.2. Основные архитектурные решения ос
- •1.4.3. Основные концепции ос
- •Прерывания
- •Системные вызовы
- •Файловая система
- •Процессы
- •Нити (потоки)
- •Понятие ресурса
- •1.5. Аппаратные среды срв
- •1.5.1. Мультипрограммная среда
- •Состояния процесса (см. Рисунок 4.).
- •1.5.2. Симметричная мультипроцессорная среда (рис. 5)
- •1.5.3. Распределенная среда (рис. 6)
- •1.6. Конфигурации клиент-серверных систем (рис.7.)
- •1.7. Средства ввода-вывода срв
- •2.1. Версии qnx
- •2.2. Posix-совместимость
- •2.3. Архитектура микроядра qnx
- •2.3.1. Микроядро
- •2.3.2. Системные процессы
- •2.3.3. Системные и пользовательские процессы
- •2.3.4. Драйверы устройств
- •2.3.5. Межпроцессное взаимодействие
- •2.3.6. Сеть qnx
- •2.4. Файлы и файловая система
- •2.4.1. Типы файлов
- •2.4.2. Жесткие ссылки
- •2.4.3. Символические ссылки
- •2.4.4. Named Special Device — именованные специальные устройства
- •2.4.5. Именованные программные каналы (fifo) (Именованный канал)
- •2.5. Структура файловой системы qnx
- •2.6. Концепция прав доступа
- •3. Начало работы
- •3.1. Интерфейс командной строки
- •3.2. Консоль командной строки
- •3.3. Соглашения по работе с командной строкой
- •3.4. Знакомство с shell
- •3.5. Обращение к домашнему каталогу
- •3.6. Базовые команды
- •3.6.1. Изменение текущего каталога
- •3.6.2. Просмотр содержимого каталогов
- •Жесткая ссылка обозначает ся так же, как файл, на который она ссылается, счетчик ссылок при этом будет иметь значение больше 1.
- •3.6.3. Создание новых каталогов
- •3.6.4. Копирование файлов
- •3.6.5. Перемещение файлов
- •3.6.6. Удаление файлов
- •3.6.7. Удаление каталогов
- •3.6.8. Просмотр содержимого файлов
- •3.6.9. Конкатенация (слияние) и просмотр файлов
- •3.6.10. Получение оперативной помощи
- •4. Объектно-ориентированное программирование
- •4.1. Системы программирования
- •4.2. Создание приложения
- •4.3. Средства отладки программ
- •5. Архитектура ос qnx
- •5.1. Типы процессов
- •5.2. Механизмы микроядра
- •5.3. Диспетчеризация потоков
- •5.4. Администратор процессов
- •5.5. Управление памятью
- •5.6. Управление пространством путевых имен
- •5.7. Пространство путевых имен
- •5.7.1. Файловая система qnx
- •5.7.2. Виртуальные устройства
- •Устройство /dev/null
- •Устройство /dev/zero
- •Устройство /dev/full
- •Устройства генерирования случайных чисел
- •5.8. Программы, процессы, нити
- •5.9. Свойства процессно-нитиевой структуры прв
- •5.10. Программный интерфейс qnx
- •5.10.1. Системные вызовы и функции стандартных библиотек
- •5.10.2. Обработка ошибок
- •5.11. Формальные параметры функции main
- •5.12. Разграничение доступа к файлам
- •5.13. Функции базового ввода/вывода
- •5.13.1. Открытие файла
- •5.13.2. Дублирование дескриптора файла
- •5.13.3. Доступ к файлу
- •6. Функции управления файловой системой
- •6.1. Смена корневого каталога
- •6.2. Смена текущего каталога
- •6.3. Создание каталога
- •6.4. Удаление каталога
- •6.5. Создание жесткой связи
- •6.6. Создание символической связи
- •6.7. Чтение символической связи
- •6.8. Переименование файла
- •6.9. Удаление файла
- •7. Микроядро
- •7.1. Запуск процессов
- •7.2. Запуск процесса из shell
- •7.3. Программный запуск процессов
- •7.3.1. Функция system()
- •7.3.2. Функции семейства exec*()
- •7.3.3. Функции семейства spawn*()
- •7.3.4. Функция fork()
- •7.3.5. Функция vfork()
- •7.4. Организация взаимодействия между процессами
- •7.5. Создание и удаление каналов Создание канала.
- •Удаление канала
- •7.6. Установление и удаление соединений с каналом Установление соединения
- •Int ConnectAttach(uint32_t nd, pid_t pid, int chid, unsigned index, int flags);
- •Разрыв соединения
- •Int ConnectDetach(int coid);
- •7.7. Передача сообщений
- •7.7.1. Посылка сообщения
- •IntMsgSend(int coid, constvoid* smsg, int sbytes, void* rmsg, int rbytes);
- •7.7.2. Прием сообщения
- •Int MsgReceive(int chid, void *msg, int bytes, struct _msg_info *info);
- •7.7.3. Посылка ответа
- •Int MsgReply(int rcvid,int status,const void* msg, int size);
- •7.7.4. Сценарии ответов
- •7.7.5. Управление сообщениями
- •7.7.6. Управление приемом сообщений
- •7.7.7. Управление передачей ответа
- •Int MsgSendv(int coid, const iov_t* siov, //Массив iov сообщения int sparts, //Количество iov сообщения const iov_t* riov, //Массив iov ответа int rbytes); //Количество iov ответа
- •Int MsgReceivev(int chid, const iov_t* riov, //Массив iov буфера int sparts, //Количество iov буфера struct_msg_info* riov);
7.3.4. Функция fork()
Функция fork() создает новый (дочерний) процесс, являющийся точной копией процесса, его породившего (родительского). При этом дочерний процесс имеет уникальный PID. Идентичные дочерние процессы могут иметь разных родителей их породивших. Дочерний процесс имеет собственную копию дескрипторов файла родительского процесса, ссылающийся на тот же самый открытый файл родителя, а также собственные копии потоков к каталогам, открытых родительским процессом. Значения tms_utime, tms_stime, tms_cutime, и tms_cstime дочернего процесса установлены в 0. Блокировки файла, предварительно установленные родителем, дочерним процессом не наследуются. Задержанные звонки таймера очищаются для дочернего процесса. Набор задерживаемых сигналов для дочернего процесса инициализируется как пустой. Оба процесса продолжают выполняться от функции fork().
Объявление функции имеет вид:
#include <sys/types.h>
#include <process.h>
pid_t fork(void);
В дочернем процессе функция возвращает 0, а в родительском - PID дочернего процесса. В случае ошибки fork() возвращает -1 родительскому процессу и устанавливает errno.
Пример:
#include <stdio.h>
#include <sys/types.h>
#include <process.h>
int main(int argc,char *argv[]){
int retval;
printf("Это родительский процесс\n");
fflush(stdout);
retval = fork(void);
printf("Кто это сказал?\n");
return EXIT_SUCCESS;
}
После вызова fork() оба процесса выполнят второй вызов printf(). Данное приложение выведет на экран следующее:
Это родительский процесс
Кто это сказал?
Кто это сказал?
Функция fflush, которая объявлена в заглавном файле ' stdio.h ' , вызывается для того, что бы сбросить буферизированный вывод.
Функция: int fflush (FILE *stream).
Эта функция заставляет любой буферизированный вывод на потоке дописываться в файл. Эти функции возвращают EOF, если происходит ошибка записи, и нуль в другом случае.
Чтобы различить эти два процесса необходимо проанализировать возвращаемое функцией fork() значение в retval. В дочернем процессе retval будет иметь нулевое значение, а в родительском - содержать PID дочернего процесса. Для пояснения рассмотрим фрагмент программы:
printf("PID родителя равен %d\n",getpid());
fflush(stdout);
if(retval = fork(void)){
printf("Это родитель, PID дочернего процесса %d\n", retval);
}else{
printf("Это дочерний процесс, PID %d\n",getpid());
}
ID процесса получается в результате вызова функции pid_t getpid (void), определеннойв файле " unistd.h ". (функция getppid возвращает ID родительского процесса)
Относительно функции fork() следует отметить, что в текущих версиях QNX она может быть успешно реализована только в процессах с одной нитью.
7.3.5. Функция vfork()
Функция vfork() создает новый процесс, как и функция fork(), но в разделяемом адресном пространстве, и блокирует родительский процесс до тех пор, пока дочерний процесс не завершится или не вызовет функцию семейства exec*().
Объявление функции имеет вид:
#include <sys/types.h>
#include <process.h>
pid_t vfork(void);
7.4. Организация взаимодействия между процессами
Процесс в QNX обеспечивает нитям интерфейс взаимодействия с нитями других процессами. Ключевым механизмом этого взаимодействия является механизм обмена сообщениями. При передаче сообщений между процессами один процесс (нити которого принимают сообщения) считается сервером, а другой (нити которого посылают сообщения) - клиентом. Поэтому механизм обмена сообщениями в QNX называют моделью "клиент/сервер". Один и тот же процесс может одновременно обеспечивать, как прием, так и посылку сообщений, т.е. выполнять функции и клиента и сервера. В частности, процесс может обеспечивать взаимодействие собственных нитей между собой посредством сообщений.
Для приема сообщений некоторая нить сервера должна создать объект, называемый каналом. В сервере может быть создан один и более каналов. В свою очередь, чтобы нити клиента получили возможность посылать сообщения в канал сервера, некоторой нитью должен быть создан объект, называемый соединением (связью) с каналом (установить соединение с каналом). С одним каналом сервера может быть установлено произвольное количество соединений одним или несколькими клиентами. Нити процессов могут создавать и уничтожать каналы и соединения по мере необходимости.