Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
25
Добавлен:
17.04.2013
Размер:
83.46 Кб
Скачать

8

СПО Лекция 6[28.02.17]

Лекция 6: Реализация взаимного исключения

  • Аппаратные средства для поддержки синхронизации.

  • Абстракции более высокого уровня для синхронизации на основе аппаратных средств.

  • Определение семафора

  • Пример использования

Способы реализации взаимного исключения

Абстракция нитей хороша, но синхронизация непосредственно на операциях чтения-записи в память слишком сложно и подвержено ошибкам.

Так что хотелось бы иметь абстракцию синхронизации, которая скрывает сложности и переносит всю тяжесть координирования множественных действий на ОС.

В этой лекции, мы рассмотрим способы построения примитивов синхронизации на базе атомарных операций, обеспеченных аппаратными средствами.

Низкий уровень

Высокий уровень

Load/store чтение/запись памяти

Lock (mutex)

Interrupts запрет прерываний

Semaphore

Test & Set инструкция «проверить и установить»

Condition variables

Monitor

Send & Receive

Есть примеры прямой аппаратной реализации инструкций взаимного исключения и переключения контекста процессов (Intel 432). Решение получается меленным, а аппаратура слишком сложной.

На основе инструкций чтения-записи памяти

Уже видели во что выливается такое решение: сложно, не симметрично, имеет место занятое ожидание

На основе запрета / разрешения прерываний (однопроцессорные)

Процесс может быть прерван в результате одного из следующих событий:

  • внутреннего (системный вызов и связанное с ним переключение контекста

  • внешнее событие (прерывание или вызов планировщика по таймеру).

На однопроцессорных машинах можно считать операцию атомарной, если во время ее выполнения невозможно переключение контекста.

Обойти внутренние события легко (не использовать «нежелательные» системные вызовы).

Блокировать внешние события можно путем запрета прерываний.

Почему бы не сделать так:

void Lock::Acquire() { asm{cli}; } //Запрет прерываний

void Lock::Release() { asm{sti}; } //Разрешение прерываний

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

В системах реального времени необходимо гарантировать отклик на прерывание в течение ограниченного интервала времени, а продолжительность критической секции может быть сколь угодно велика.

Основная идея: управлять флажком разрешения входа в критическую секцию и использовать взаимное исключение для доступа к этому флагу.

Class Lock {

bool busy;

public:

Lock() { busy = false; }

void Acquire();

void Release();

};

void Lock::Acquire ()

{

// Запрет прерываний

if(busy) {

....................// (1)? разрешить прерывания ?

// поставить в очередь к этому Lock

....................// (2)? разрешить прерывания ?

schedule(); // заснуть и передать управление другому

}

else

busy = true;

// Разрешить прерывания

}

void Lock::Release ()

{

// Запрет прерываний

if(очередь не пуста) {

// исключить первого из очереди

// поставить в очередь готовых

}

else busy = false;

// Разрешить прерывания

}

Запрет прерываний гарантирует что между проверкой и установкой флага busy никто не сможет вмешаться. Гарантирует что два процесса не смогут получить разрешение на вход в критическую секцию одновременно.

Заметим, что Release – не приводит к переключению контекста!

Когда разрешать прерывания?

(1) Если разрешить прерывания до включения процесса в очередь ожидающих, тоRelease может проверить очередь и обойти исключение процесса из очереди.

(2) Если разрешить прерывания после включения процесса в очередь ожидающих, но доschedule, то другая нить,вызвавRelease, может поставить процесс в очередь готовых, а сам процесс считает , что он должен заснуть и вызываетschedule.

Разрешение прерываний можно переложить на schedule! При вызове в стеке сохраняется текущее состояние обработки прерываний, соответственно, при восстановлении контекста активизируемой нити восстанавливается ее состояние обработки прерываний.

Соседние файлы в папке вар1