Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СРВ(к.р.1).docx
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
110 Кб
Скачать
☆

Синхронизация задач.

Это тоже одна из важных проблем, как для СРВ, так и для многопользовательских систем. Под синхронизацией в ОС понимается согласованность действий (а не "попадание" в точные моменты времени). Первый случай, когда это необходимо: когда функции, выполняемые задачами, связаны друг с другом. Например, пока одна задача не закончит вычисления, другая не может начать работу. Или, в зависимости от внешних условий (они анализируются), порождаются разные задачи. Второй случай: упорядочивание доступа к общему разделяемому ресурсу. Третий: когда нужно поставить выполнение задачи в зависимости от внешнего события. Четвертый (относительно редкий): синхронизация задач во времени.

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

message, mail box, signal, event, proxy.

В русскоязычной литературе часто все варианты переводят как "сообщение", разделяя их на "явные" и "неявные" (это, например, семафоры). Объем сообщений: от бита и выше (ограничиваясь только техническими средствами). Кроме того, сообщения делят на синхронные и асинхронные. Здесь тоже "не как, в схемотехнике": асинхронное сообщение может быть доставлено, только когда готовая задача стала выполняться. Получается, что на передачу управления между задачами асинхронное сообщение не влияет. Синхронные же сообщения могут влиять на передачу управления. Например, получили сообщение в виде прерывания -- задача заблокировалась. Обычно передача управления происходит, если сообщение передано от более высокоприоритетной задачи. Организация обмена непосредственно между задачами повышает надежность, но усложняет планировщик. Кроме того, нужно иметь менеджер сообщений (отдельный узел для организации очередности и т.п.). Если использовать "почтовый ящик" -- все гораздно проще, но "подвох" заключается в том. что тот, кто записывает сообщение, не знает, считали его или нет, а, поскольку объем ограничен, последующее будет затирать предыдущее.

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

Пример: есть очередь печати. Кто-то из пользователей отменяет свое задание. Можно ли его (это сообщение) поместить последним? Нет, это бессмысленно. Нужно использовать наследование приоритетов. Кроме того, очереди сообщений могут обрабатываться как одним общим супервизором, так и супервизором, созданным для наиболее важных задач (см. выше про жесткое и мягкое время).

Разделяемые ресурсы.

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

  • считать все в буфер какого-то драйвера

  • продолжить работу предыдущей программы, а данные обрабатывать параллельно

Также распространенная ошибки, связанная с прерываниями:

  • Например, присвоили прерываниями пользовательским очень высокий приоритет, но системой он, согласно таблице прерываний, подменяется с назначенного пользователем на тот, что выбрано в ОС.

  • Необоснованное использование глобальных переменных. Особенно, если эти переменные используются потоками в рамках одного модуля.

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

Семафоры и мьютексы.

Лекция 4

Ошибки, которые являются следствием гонок, характерны для двух случаев:

  • Обращение нескольких задач к общему ресурсу

  • Гонки, которые возникают как следствие совпадения нескольких условий

Наиболее часто возникают в ОС при использовании алгоритмов с вытеснением.

Для избежания ошибок:

  • стараются не использовать алгоритмы с вытеснением. Такой подход возможен не всегда.

  • могут создать сервер для конкретного ресурса. Это может быть управление как физич устройствами (клиент-сервер), так и серверы управления глобальными переменными.

  • на время доступа к разделяемым ресурсам запрещают прерывания. Это тоже не всегда возможно.

  • Используют семафоры

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

Когда говорят о семафоре во втором смысле этого слова, то подразумевают своеобразный счетчик. Любая задача, которая обратилась к ресурсу, уменьшает значение этого счетчика на единицу. После завершения задача увеличивает счетчик на единицу. При значении счетчика "0" все задачи находятся в состоянии ожидания.

Например: принт-сервер (см. рис. "Задачи принт-сервера")