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

Задание №2

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

Объяснить достоинства и недостатки каждого из методов взаимного исключения или организации доступа к разделяемым ресурсам. Привести примеры использования объектов синхронизации в Windows 2000/XP

Классической задачей при параллельном программировании является задача критической секции".

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

Критической секции соответствует протокол входа, а за ней следует протокол выхода. Итак, процесс имеет вид

process CS[i = 1 to n]

{ while (true) {

[протокол входа];

[критическая секция];

[протокол выхода];

[некритическая секция]; } }

Протоколы входа должны удовлетворять следующим свойствам.

1. "Взаимное исключение": й любой момент только один процесс может

выполнять свою критическую секцию.

2. "Отсутствие взаимной блокировки": если несколько процессов пытаются войти в свои критические секции; хотя бы один это осуществит.

3. "Отсутствие излишних задержек"; если процесс хочет войти в сбою критическую секцию, а другие выполняют некритические секции или завершены, то процессу разрешается вход в упомянутую критиче­скую секцию.

4. "Возможность входа": процесс, который пытается войти в критиче­скую секцию, когда-нибудь это сделает.

Свойство "взаимное исключение" нарушается, если два процесса на­ходятся в своих критических секциях.

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

Пример. Пусть inl и in2 — логические переменные. Процесс SI (S2) находится в критической секции, в то время как inl (in.2) присваивается "истина".

Для взаимного исключения требуется истинность состояния MUTEX: -i(inl^in2).

Программа для критической секции (крупномодульное программирование)

bool inl = false, in.2 = false;

## MUTEX : -.(inl Л in2) — глобальный инвариант

1) process CS1 {

2) while (true) {

3) < await (!in2) inl = true; > # вход

4) [критическая секция];

5) inl = false; # выход

6) [некритическая секция];

7) }

8) }

9) process CS2 {

10) while (true) {

11) < await (!inl) in2 = true; > # вход

12) [критическая секция];

13) in2 = false; # выход

14) [некритическая секция];

15) }

16)}

14.2. Активные блокировки

Можно рассмотреть произвольное число п процессов, но использовать одну логическую переменную (вместо п логических переменных в каждом процессе).

Пусть lock — логическая переменная. Если один из процессов находится в критической секции, то в предыдущей программе inl V in2 = true. Пусть lock принимает,значение true, если хотя бы какой-либо процесс находится в критической секции, а если нет процес-сов в критической секции, то lock = false. Проиллюстрируем применение этой переменной для двух процессов (п = 2).

Замечание 1. Инвариант, рассмотренный выше именно -i(inl ^ in2)), нельзя сформулировать при помощи переменной lock. Однако использо-вание lock позволяет поддерживать этот инвариант; это вытекает из сле-дующего примера:

bool lock = false; process CS1 { while (true) {

< await (!lock) lock = true; > # если !lock, то вход . .

# разрешен: входим, [критическая секция];

lock = false; # выходим из критической секции и сразу

# устанавливаем lock = false [некритическая секция];

}}

process CS2 { while (true) {

< await (!lock) lock = true; > # если ilock, то вход

# разрешен: входим... [критическая секция];

lock = false; # выходим из критической секции и сразу

# устанавливаем lock = false [некритическая секция];

}}

Замечание 2. Использование логической переменной lock при произволь­ном числе процессов аналогично.

14.3. Протокол "проверить-установить"

Протокол "проверить-установить" (Test and Set, кратко — TS) полу­чает в качестве аргумента переменную lock, в неделимом действии при­сваивает ей значение true, а затем возвращает предыдущее сохраненное значение переменной lock. Это описывается так:

bool TS(bool lock) {

(bool initial = lock; # сохраняем начальное значение lock = true; # ставим lock внутри неделимого действия return initial;) # возвращаем предыдущее значение

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

Критические секции на основе протокола "проверить-установить" (циклическая блокировка).

1) bool lock = false;

2) process CS[i = 1 to n] {

3) while (true) {

4) while (TS(lock)) skip; # протокол входа

5) [критическая секция];

# на основании свойства TS здесь lock == true

6) lock = false; # восстанавливаем возможность доступа

Ф к критическим секциям

7) [некритическая секция];

8) }

9)}

Свойства этой программы следующие:

взаимное исключение выполнено, ибо если lock = false и несколько процессов хотят войти в критическую секцию, то только один войдет в нее, и произойдет присваивание lock = true (другие не войдут);

отсутствие взаимной блокировки выполнено: если оба процесса находятся во входных протоколах, то lock имеет значение false, и лишь один из них, войдя в критическую секцию, сразу изменит (с помощью TS) значение переменной lock на true (второй процесс войти в критическую секцию не сможет);

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

если используется стратегия планирования, справедливая в слабом смысле, то возможность входа не гарантируется (возможен поток зна­чений false у переменной lock как раз в моменты проверок этого значе­ния процессом); однако если стратегия планирования справедлива в силь­ном смысле, то возможность входа гарантируется.