Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Судаков / Лекции / lec15_sinxr.ppt
Скачиваний:
24
Добавлен:
20.03.2015
Размер:
253.44 Кб
Скачать

Спин-блокировки

Спин-блокировка – использование бесконечного цикла (вращения) для проверки условия возможности доступа к ресурсу

Самый быстрый тип блокировки

Используется, когда время выполнения критической секции мало

Постоянно занимают процессор

Спин блокировка с атомарными операциями

Test-and-set lock

Атомарная машинная инструкция tas(addr,val)

Атомарно считывает предыдущее значение из области памяти addr и устанавливает значение этой области памяти в val

static int lock_var=0;

void lock(int* var){ while(tas(var,1));

}

void unlock(int* var){ *var=0;

//или //atomic_set(var,0);

}

Блокировки без атомарных операций

Используются

последовательные операции записи, чтения, проверки нескольких переменных

Алгоритм Петерсона

Два процессора 0 и 1

me() – номер текущего процессора

Три общих переменных

Flag[2] – кто ожидает

Victim – кто захватывает

int flag[2]={0,0}; Int victim;

void lock(){ flag[me()]=1; victim = me();

while(flag[!me()] && victim==me());

}

void unlock(){ flag[me()]=0;

}

Свойства

Алгоритм Петерсона обеспечивает взаимоисключающий доступ к критическому разделу

Алгоритм Петерсона гарантирует отсутствие бесконечного ожидания

Доказательство

взаимоисключенияЗапишем последовательность действий обоих процессоров

Запись0(flag[0]=1)->запись0(victim=0) ->чтение0(flag[1])->чтение0(victim)

Запись1(flag[1]=1)->запись1(victim=1) ->чтение1(flag[0])->чтение1(victim)

Допустим, что оба процессора вошли в критический раздел

Пусть для определенности процессор 0 записал значение переменной victim последним

Все значения flag[] уже записаны

Тогда последовательность записи этой переменной была следующей

запись1(victim=1)->запись0(victim=0)

Раз процессор 0 вошел в критический раздел, то он прочитал

flag[1]=0, victim=0

Значит последовательность операций была

запись0(victim=0)-> чтение1(flag[1]==0)

Учитывая первые 3 уравнения

Запись1(flag[1]=1)->запись1(victim=1) ->запись0(victim=0)->чтение1(flag[1]==0)

Получается, что значение переменной flag[1] поменялось после записи victim, а такого не может быть

Доказательство отсутствия бесконечного ожидания

Пусть процессор 0 бесконечно ожидает в цикле, тогда flag[1]=1 и victim=0

Такая ситуация может возникнуть только

когда процессор 1 выполнил команду flag[me()]=1; и еще не выполнил команду

victim = me();

Эти две команды идут подряд, поэтому, если выполнилась первая, то вторая тоже скоро выполнится

Алгоритмы для N процессоров

Более сложные

Используется следующий принцип:

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

Только для одного процессора его комбинация номер-метка позволяет войти в критический раздел

Блокировка в состоянии конфликта

Спин-блокировка - сложный алгоритм, который выполняется несколькими процессами одновременно

Когда за захват блокировки состязаются потоки – блокировка находится в состоянии конфликта (contended)

Различные алгоритмы требуют разного количества операций при обработке состояния конфликта при большом количестве потоков

Эффективность блокировок

Существуют алгоритмы порядка O(n2) и O(n) операций для выполнения проверок в состоянии конфликта

При увеличении количества потоков время выполнения может расти из-за конфликтов при захвате

Спин-блокировки для реальных систем

Атомарные операции – медленные

Запись в общую память может выполняться не сразу, а буферизироваться процессором

Компилятор может пытаться оптимизировать код и изменять порядок операций

Необходимо использовать барьеры памяти, компилятора

Существует множество библиотечных функций для обеспечения блокировок

Соседние файлы в папке Лекции