Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
8-CHto-takoe-mnogozadachnost.docx
Скачиваний:
4
Добавлен:
18.09.2019
Размер:
5.81 Mб
Скачать

Разделение ресурсов в чем состоит проблема

Что может являться разделяемым ресурсом. (Примеры, ситуации)

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

Приведем пример (проект из практик – взаимное влияние двух Задач, передающих данные через UART).

??? Для рассматриваемых примеров надо нарисовать диаграммы.

1) График взаимодействия двух Задач – это происходит, когда передает Low-Задача и становится готовой к исполнению Med-Задача.

2) Решение-1 – использование переменной-флажка. Любая Задача, желающая использовать ресурс, сначала проверяет и устанавливает флажок.

Что делать, если флажок уже установлен? Перевести Задачу в состояние ожидания (лучше, чтобы это произошло автоматически, и флажок должен запоминать, какую Задачу он подвесил). Кроме того, возникает противоречие между приоритетами Задач (инверсия) и желанием не разрывать операцию. Как выполнять операцию «проверить_и_установить»? ‑ о «критических секциях». Флаг тоже является разделяемым ресурсом, его проверку-изменение надо выполнять неразрывно.

График взаимодействия двух Задач при использовании флажка. После того, как Med-Задача подвисла, Low-Задача заканчивает использование ресурса и освобождает флажок. Теперь самое время продолжить выполнение Med ‑Задачи, и лучше, чтобы это произошло автоматически при освобождении флажка. Med-Задача начинает использование ресурса, и через некоторое время заканчивает и освобождает флажок.

3) Ситуация, когда ресурс занят Low-Задачей, и несколько Задач с более высоким приоритетом опрешивают флажок и подвисают. Когда Low-Задача освободит ресурс, должна продолжиться Задача с наиболее высоким приоритетом. Надо бы помнить все ожидающие Задачи, чтобы можно было решить, какую возобновить.

4) Ситуация, когда возникает явление затяжной инверсии приоритетов. Способ разрешения при помощи динамического изменения приоритетов Задач. (Будет рассмотрено в разделе «Мьютексы»)

5) Возникновение тупика, если две Задачи нуждаются каждая одновременно в паре ресурсов.

Пример тупика (взаимоблокировки).

Признаки возможности возникновения взаимоблокировок:

1) Условие взаимного исключения – к ресурсу обращается больше Задач, чем он может обслужить.

2) Условие удержания при ожидании – Задача, ожидающая второго ресурса, удерживает первый.

3) Невозможно принудительно «отобрать» ресурс у захватившей Задачи.

4) Условие циклического ожидания – в графе «захватов» и «ожиданий» ресурсов имеется цикл.

Решение проблемы – наложение ограничений на поведение Задач – например, а) запрещать удержание захваченных ресурсов при невозможности получить еще один требуемый б) пытаться захватывать ресурсы (семафоры) только в определенном порядке.

Критическая секция кода

Критическая секция кода - это фрагмент кода, который нельзя разделять при выполнении. Если код критической секции начал выполняться, его нельзя прерывать. Чтобы обеспечить это, обычно перед выполнением критической секции кода прерывания запрещают, а после выполнения снова разрешают

Для разграничения доступа хочется иметь возможность узнать о факте освобождения UART и немедленно вслед за этим занять UART другим обработчиком-передатчиком.

Простейшим мог бы быть способ, использующий опрос занятости канала задачей, ожидающей своей очереди на передачу. Недостаток – как у любого программного опроса готовности, нерациональное использование процессорного времени. Хочется иметь аналог аппаратного прерывания: как только канал освободится, надо активировать задачу с наивысшим приоритетом среди задач, ожидающих канала.

Как же можно обеспечить целостность пакетов.

  1. Запрет прерываний на время передачи пакета (критические секции кода). Как можно это делать а) процессорные команды DI и EI – недостаток их использования. б) сохранение старого содержимого SR в стеке – когда это может привести к неприятности. в) сохранение SR в локальной переменной. Запрет прерывания увеличивает время реакции на аппаратные запросы прерываний, поэтому участки, на которых прерывания запрещены, должны быть как можно короче.

  2. Запрет диспетчеризации (переключения задач) на время передачи пакета. Эти два способа плохи тем, что если станет готовой к исполнению задача (или обработчик прерывания) с более высоким приоритетом, которым не требуется занятый ресурс, они не смогут исполняться, пока не закончится критическая секция кода.

  3. «Проба-и-установка» флага занятости. Либо использовать процессорную команду, которая одна делает «пробу-и-установку», либо запрещать на это время прерывания. Т.е. «проба-и установка» сама является критической секцией. По Лаброссу эта техника используется при программировании без ОСРВ.

  4. Динамическое изменение приоритетов.

  5. Специальные сервисы ОСРВ для синхронизации (это будет рассмотрено далее).

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

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

В нашем примере, если выделяем действие передачи данных через последовательный интерфейс в отдельную задачу-П, задача-П должна работать лишь тогда, когда хотя бы одна задача О/З сформировала пакет. И, наоборот, задача-О/З может находиться в состоянии ожидания (заблокирована задачей-П), если у последней исчерпано место для данных от задачи-О/З.

Резюме. Что же делает ядро реального времени. Оно отслеживает а) внешние асинхронные события, используя механизм аппаратных прерываний, б) события при выполнении текущей задачи (вобще, задач в состоянии Run) и а) и б) могут сделать возможным продолжение ожидающих задач (перевод их из состояния Wait в состояние Ready), в) выполняет планирование и диспетчеризацию, т.е. передачу управления задаче с наивысшим приоритетом среди готовых к исполнению.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]