Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Взаимоисключения. Понятие критической секции. Устаревшие подходы к организации взаимного исключения.




Ситуация гонок (race condition):

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

Например: 2 процесса имеют доступ к разделяемой памяти. В ней есть переменная целого типа со значением 5. Оба процесса пытаются увеличить на 1 ее значение одновременно. По идее она будет =7. Для этого надо загрузить значение в регистр, далее увеличить на 1 и выгрузить в память. Допустим 1й процесс выполнил MOV для перемещения из памяти в регистр. В этот моментпроизошло прерывание по таймеру и процесс снят с исплонения. В это время 2й процесс тоже выполнил MOV и INC, а потом снова MOV для перемещения из регистра в память => Переменная =6/. 1й процесс за это время дождался своей очереди и снова выполняется. Но первую MOV он уже выполнил, так что в его регистре уже было 5, далее INC и MOV обратно и имеем значение 6. Здесь возникает ситуация гонок.

Более серьезный пример:

301: 1000$ - 100$ = 900$ 1й оператор переводит 100$ с 301 на 768.

505: 1500$ + 200$ = 1700$ 2й оператор переводит 200$ с 768 на 505.

768: 2000$ - 100$ = 1900$

Пусть процесс запущенный 2м оператором был прерван после операции чтения остатков (1500 и 2000 соотв-но). Эти остатки он сохранил в своих структурах. Произошло прерывание, 1й процесс считает остатки с 301 и 768 (1000 и 2000 соотв-но) и все сделал верно. Затем снова 2й процесс, он получает 1700 и 1800, именно это она записывает в БД, в результате владелец 768 обнаружит недостачу. Нежелательные эффекты возможны тогда, когда один из участников даже не производит изменений, а только читает данные.

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

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

Требования, налагаемые на механизм взаимного исключения:

1) 2 и более процессов не должны ни при каких условиях находится одновременно в критических секциях.

2) В проге не дб предположений о скорости выполнения процесса и о количестве процессоров в системе.

3) Процесс находящийся вне критической секции не дб причиной блокировки др. процессов.

4) Недопустима ситуация вечного ожидания.

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

Использование блокировочной переменной:

Пусть есть некоторые данные, доступ к которым осущ-т несколько процессов. Для управления этим заведем в разделяемой памяти целочисленную переменную и примем соглашение что значение переменной: S=1 - означает что с раздел данными никто не работает, S=0 – с раздел данными работает 1 из процессов.

При запуске системы присвоим S=1 и доступ к данным будем осуществлять по схеме:

While (S==0) {} // пустой цикл, работает пока нельзя входить в критич. секцию

S=0; // запретим доступ другим процессам.

Section(); // функция

S=1; // разрешим доступ к разделяемым данным.

Все процессы имеющие доступ к раздел данным должнв следовать такой схеме. Выполнение процесса мб прервано в тот момент, когда он уже увидел число 1 в S и вышел из цикла while, но присвоить S=0 не успел. В этом случае другой процесс может тоже увидеть значение =1 и присвоить S=0 и войти в секцию. Затем управление будет передано 1му процессу, который проверку значения уже произвел, далее он S=0 и войдет в секцию. В результате оба процесса окажутся в секции, т.к. необходима атомарность (непрерывность) некоторых действий при организации взаимоисключений. Между while и S=0 не дб прерываний!

Запрет на внешние прерывания:

1) Запрет прерываний годится для кратковременных критич. секций с небольшим кодом.

2) Запрет прерываний годится только для работы с данными, нах-ся в ОЗУ.

3) Касается только 1 процессора, в системе с несколькими процессорами не дает эффекта.

4) В комбинации с активным ожиданием запрет прерываний приводит в зависанию системы.

5) Допускать запрет прерываний пользовательскими процессами просто опасно.

Чередование:

Процессы по очереди передают друг другу право работы с разделяемыми данными.

For {;;} // бесконечный цикл

{While (turn!=0) {}

Section(); // критическая секция 1й процесс

turn:=1;

NoneCriticalSection(); }

For {;;}

{While (turn!=1) {}

Section(); // критическая секция 2й процесс

turn:=0;

NoneCriticalSection(); }

 

Здесь показаны 2 процесса осуществляющие доступ к раздел данным в соотв. с маркером чередования (turn). Значение turn=0 – право на доступ имеет 1й процесс, =1 - …2й процесс. Каждый из процессов завершив критич. секцию передает ход другому процессу изменив turn и переходит к выполнению действий без доступа к раздел. данным.

Такой способ гарантирует процессам невозможность оказаться в критич. секции одновременно. Однако, если один из процессов передав ход другому быстро выполнит некритич действия и снова войдет в критич секцию, может оказаться что 21 процесс не дошел до критич секции и не передал ход 1ому. В результате 2й процесс не нуждаясь в доступе к раздел данным будет мешать доступу к этим данным 1му процессу.

Алгоритм Петерсона: (рассмотрим для 2х процессов)

В раздел памяти надо создать массив из 2х логич переменных interes[2]. Логич переем показывает нуждается ли соотв процесс в выполнении критич секции. Во время выполнения критич. секции соотв логич величина дб истина для конкретного процесса. Кроме того введем в раздел памяти переменную waits, которая будет показывать который из процессов в случае столкновения должен подождать завершения критич. секции другого процесса.

Принцип алгоритма:

Показать свою заинтересованность во входе в крит секцию – interes[0]:=true

Процесс заявляет о своей готовности подождать, если это надо. Процесс будет заносить в переем waits свой номер.

Void enter_section();

{ interes[0]:=true;

Waits:=0;

While (waits==0 && interes[1]) {} 1й процесс

}

Void leave_section();

{interes[0]:=false;}

 

Void enter_section();

{ interes[1]:=true;

Waits:=1;

While (waits==1 && interes[0]) {} 2й процесс

}

Void leave_section();

{interes[1]:=false;}

 

Алгоритм состоит из 2х функций: вход в критич. секцию и выход из нее. Единств недостаток – активное ожидание ( {} ).

 

 


Поделиться:

Дата добавления: 2015-01-14; просмотров: 209; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты