Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вопросы и ответы по ОС.doc
Скачиваний:
37
Добавлен:
27.08.2019
Размер:
3.35 Mб
Скачать

27 Вопрос. Мьютексы

Иногда используется упрощенная версия семафора, называемая мьютексом (mutex, сокращение от mutual exclusion - взаимное исключение). Мьютекс не способен считать, он может лишь управлять взаимным исключением доступа к совместно используемым ресурсам или кодам. Реализация мьютекса проста и эффективна, что делает использование мьютексов особенно полезным в случае потоков, действующих только в пространстве пользователя.

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

Напротив, если мьютекс заблокирован, вызывающий поток блокируется до тех пор, пока другой поток, находящийся к критической области, не выйдет из нее, вызвав процедуру mutex_unlock. Если мьютекс блокирует несколько потоков, то из них случайным образом выбирается один.

[Крищенко: метода sys_linux]

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

Для решения задачи синхронизации в ядре Linux существует множество механизмов синхронизации, обычно доступные после включение файла linux/sched.h, такие как:

- переменные. локальные для каждого процессора (per-CPU variables), интерфейс которых описан в файле linux/percpu.h;

- семафоры (linux/semaphore.h) и спин-блокировки linux/spinlock.h;

- семафоры читателей и писателей (linux/rwsem.h);

- мьютексы реального времени (linux/rtmutex.h);

- механизмы ожидания выполнения (linux/completion.h);

- атомарные переменные (описаны в архитектурно-зависимых файлах atomic*.h)

Семафор в ядре представляет собой механизм, позволяющий ограничить кол-во нитей, одновременно выполняющихся в некоторой области кода. Это количество называется значением семафора. Мьютекс представляет собой семафор со значением, равным единице. Для обозначения открытия и закрытия семафоров в ядре используются термины down и up соответственно.

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

Кроме обычных мьютексов и семафоров, в ядре существует новый интерфейс для мьютексов реального времени (rt mutex).

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

Для реализации писателей и читателей в ядре Linux существуют специальные версии семафоров и спин-блокировок. Мьютексы реального времени не имеют реализации для случая читателей и писателей, поэтому разработчик должен сделать осознанный выбор механизма синхронизации.

can_sleep() ??

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