logo
HCS12 с применением языка С - royallib

8.6.1. Конкуренция Другой рассказ

Я провожу много времени в поездках. Однажды я проезжал от Ларами до Форта Коллинз, где должен был подготовить конференцию. На прекрасном и живописном шоссе U.S. 287, мне встретился протяженный участок ремонтируемой дороги. Эта магистраль — асфальтированная дорога с двумя встречными полосами.

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

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

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

Проблема конкуренции появляется, когда задача с низким приоритетом выполняет некоторую критическую часть своего кода или использует критический ресурс. Если она будет прервана, то не сможет корректно завершить свою программу, даже если впоследствии и получит необходимое процессорное время. Например, представим себе, что задача использует ATD микроконтроллера 68HC12, выполняя аналого-цифровое преобразование. Если задача начнет преобразование и будет прервана до его окончания, то произойдут ошибки. Эта ситуация может стать еще более сложной, если ставшая активной высокоприоритетная задача также должна использовать модуль ATD.

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

• Запрет на прерывания: Прерывания блокируются, когда задача выполняет критическую часть программного кода. В микроконтроллере 68HC12 это выполняется с помощью команды SEI (установить маскирование прерывания). Как только критическая часть кода закончена, прерывания могут быть снова разрешены командой CLI (очистить маскирование прерывания).

• Использование семафоров или блокировок; семафор или блокировка может использоваться, чтобы указать, что критический ресурс не доступен для использования, потому что это используется в настоящее время другой задачей. Регулировщики с флажками из нашего рассказа как раз и использовали семафоры (знаки «остановиться» и «продолжать осторожное движение») чтобы запрещать или разрешать доступ к критическому ресурсу. Прежде, чем часть программы сможет использовать критическую часть кода, она должна выяснить, доступен ли ресурс.