- •1. Общая х-ка систем реального времени
- •4._Архітектура ос qnx-6.
- •5. Основні компоненти ос рч та їх загальна характеристика (планувальник задач та диспетчер (ядро), обробники переривань, програма стеження за часом, адміністратор ресурсів).
- •6.Правила диспетчеризації потоків в сучасних ос рч (fifo,rr,тощо). Рівні пріоритетів. Механізми синхронізації.
- •8.Стани задач в ос рч
- •9.Планування та диспетчеризація задач в ос рч. Чинники та алгоритми планування.
- •10. Механізми взаємодії задач в ос рч (повідомлення, схеми обміну повідомленнями).
- •11. Концепция потоков и процессов
- •13. Архітектура ос qnx-6.
- •12. Методи синхронізації потоків.
- •14. Алгоритми планування задач в ос qnx-6
- •15. Дисципліни та правила диспетчеризації потоків в ос qnx-6.
- •16. Стани потоків в ос qnx-6
- •17. Запуск процесів та потоків в ос qnx-6.
- •18. Створення потоків в ос qnx-6
- •19. Копіювання процесів в ос qnx-6
- •20. Атрибути потоків в ос qnx-6.
- •21.Синхронизация потоков по мютексу.
- •22.Синхронизация потоков по семафору.
- •23.Синхронізація потоків за „приєднанням”. (взято из Кертона, изменяй, когда переписываешь)
- •24. Синхронізація потоків за «бар'єром».
- •25. Синхронізація операцій читання-запису.
- •26.Синхронізація потоків за ”чекаючим блокуванням”.
- •27.Алгоритм взаємодії потока-виробника та потока-приймача інформації на основі „чекаючих блокувань”.
- •28.Синхронізація потоків за „умовними змінними”.
- •29.Пули (pool) потоків та їх використання.
- •30. Алгоритм керування числом потоків в пулі потоків.
- •31. Обмін повідомленнями за моделлю "клієнт - сервер".
- •33. Обмін повідомленнями за моделлю "клієнт – сервер - субсервер". Смотри далее.
- •34. Обмін повідомленнями за моделлю "клієнт – сервер - субсервер".
- •35. Механізм обміну повідомленнями між клієнтом та сервером в ос qnx-6.
- •36. Визначення потрібного сервера та жетон клієнта.
- •37. Обмін повідомленнями великого розміру.
- •38. Складені повідомлення та механізм iov.
- •39. Повідомлення за типом “імпульс”. Передача та прийом імпульсу.
- •40. Механізм стеження за часом. Годинники та таймери.
- •41. Механізм стеження за часом. Схеми повідомлення про «тайм-аут».
- •42. Створення та використання таймерів в ос qnx-6.
- •43. Тайм-аути ядра ос qnx-6.
- •44. Обробка переривань в ос qnx-6.
- •45. Розподіл загальної пам'яті між процесами (розповісти про shm_open, mmap, shm_unlink).
- •46. Мікроядро Neutrino та його можливості.
- •47. Розробка консольних проектів срч в середовищі qnx-6.
- •48. Мікроядро Photon та його можливості.
- •49. Розробка проектів срч в середовищі Application Builder.
25. Синхронізація операцій читання-запису.
Используется для синх-ции «писателей» и «читателей» при работе с общим ресурсом по схеме: несколько «читателей» используют ресурс при отсутствии «писателей», один «писатель» использует ресурс при отсутствии «читателей» и других «писателей».
При работе потоков возникает необходимость разделения некоторых структурных данных. Ясно, что в любой момент времени только 1 поток может записывать в структуру, поэтому поток «писатель» должен получить эксклюзивную блокировку чтения/записи – rwlock. При этом право доступа к ресурсу контролируется на добровольных началах, т.е. за синхронизацию потоков «писателей» и потоков «читателей» отвечает программист.
Для блокировок чт/зап используются вызовы:
инициализация внутренних областей памяти для rwlock блокировок
int pthread_rwlock_init(pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr);
Эта функция принимает аргумент lock и инициализирует его атрибутами, указанными в attr.
Уничтожение блокировок
int pthread_rwlock_destroy(pthread_rwlock_t *lock);
Установка атрибутов
int pthread_rwlockattr_init();
int –“– _destroy();
int –“– _getpshared();
int –“– _setpshared();
Нельзя использовать блокировку, которая еще не инициализирована или уже уничтожена.
Выбор типа блокировки: «читателям» - не эксклюзивный доступ, «писателю» - эксклюзивный. По «читателям» и «писателям» блокировки разные.
int pthread_rwlock_rdlock(pthread_rwlock_t *lock); - блокировка потока, если ресурс недоступен.
int pthread_rwlock_tryrdlock(pthread_rwlock_t *lock); - не блокирующий вызов для «читателя», при неудаче – возвращается код ошибки.
int pthread_rwlock_wrlock(pthread_rwlock_t *lock); - блокирующий вызов для «писателя».
int pthread_rwlock_trywrlock(pthread_rwlock_t *lock); - не блокирующий вызов.
Как и блокирующий так и не блокирующий вызов получает блокировку, если она доступна, но если блокировка недоступна, то при блокирующем вызове поток будет блокированным, а при не блокирующем вызове – нет.
Освобождение блокировки
int pthread_rwlock_unlock(pthread_rwlock_t *lock);
После того, как поток выполнит операции с ресурсом, он обязан освободить блокировку, которая, возможно, ожидается другим потоком.
Введение rwlock блокировки связано с тем, что синхронизацию «читателя» и «писателя» невозможно организовать ни с помощью мютекса, который недопускает несколько «читателей», ни с помощью семафора, который с «читателем» может допустить «писателя».
26.Синхронізація потоків за ”чекаючим блокуванням”.
Иногда при выполнении синхронизации нам нужно чтобы поток ожидал некоторого события. Например, когда доступны данные от устройства, или когда данные сохранены на диск и т.д. Ещё одна особенность данной ситуации состоит в том, что одного и того же события могут ожидать несколько потоков. Для таких целей можно использовать либо условную переменную либо ждущую блокировку.
Для выполнения метода „ждущих блокировками” необходимо выполнить некоторые опреации:
-захват внутреннего мютекса(mutex) библиотек ждущих блокировок
int pthread_sleepon_lock(void);
-освобождение мютекса
int pthread_sleepon_unlock(void);
-ожидания события по указанному адресу
int pthread_sleepon_wait(void*addr);
-отправки сигнала одному из потоков
int pthread_sleepon_signal(void*addr);
-отправки сигнала нескольким потокам
int pthread_sleepon_broadcast(void*addr);
Отметим, что несмотря на префикс «pthread_», вышеперечисленные функции не предусмотрены стандартами POSIX.
Для наглядного примера можна написать такую программу, где один поток является поставщиком данных, а другой потребителем:
Для удобства написания такой программы нам нужно ввести переменную flag, которая будет принимать значения 0 если данных нет, или 1 если данные есть.
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
volatile int flag=0;
void * consumer (void * not_used)
{printf(“This is consumer\n”); \\потребитель
while(1)
{ pthread_sleepon_lock(); //захват внутреннего мютекса
while(!flag) pthread_sleepon_wait(&flag);
sleep(1); //имитация обработки данных
flag=0; //данных нет
pthread_sleepon_unlock();}}
Блокировка мютекса надо чтоб обеспечить доступ к флагу потоку потребителя для его проверки, а поток - поставщик в данный момент не может изменять наш флаг. Если же не разблокировать в конце функции мютекс, тогда поток поставщик никогда не изменит флаг, и программа не будет выполнять никакие операции.
Рассмотрим функцию производителя: void * producer(void * not_used){
while(1){ sleep(2); // имитация получения данных
pthread_sleepon_lock();
flag=1; // данные теперь есть
pthread_sleepon_signal(&flag); //посылаем сигнал потоку
pthread_sleepon_unlock();
}}
int main()
{ printf(‘Example\n’);
pthread_create(NULL,NULL,producer,NUUL);
pthread_create(NULL,NULL,consumer,NUUL);
sleep(30);}
