Студопедия

Главная страница Случайная страница

Разделы сайта

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






Первая попытка






Наиболее общим механизмом может служить ограничение, согласно которому к некоторой ячейке памяти в определенный момент времени может осуществляться только одно обращение. Воспользовавшись этим ограничением, зарезервируем глобальную ячейку памяти, которую назовем turn. Процесс (Р0 или Р1), который намерен выполнить критический раздел, сначала проверяет содержимое ячейки памяти turn. Если значение turn равно номеру процесса, то процесс может войти в критический раздел; в противном случае он должен ждать, постоянно опрашивая значение turn до тех пор, пока оно не позволит процессу войти в критический раздел. Такая процедура известна как пережидание занятости (busy waiting), поскольку процесс вынужден, по сути, не делать ничего полезного до тех пор, пока не получит разрешение на вход в критический раздел. Более того, он постоянно опрашивает значение переменной и тем самым потребляет процессорное время.

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

Говоря формально, имеется глобальная переменная

int turn = 0;

На схеме (а) показана программа для двух процессов. Это решение гарантирует корректную работу взаимоисключения, однако имеет два недостатка. Во-первых, при входе в критический раздел процессы должны строго чередоваться; тем самым скорость работы диктуется более медленным из двух процессов. Если процессу Р0 вход в критический раздел требуется раз в час, а процессору Р1 — 1000 раз в час, то темп работы Р1 будет таким же, как и у процесса Р0. Во-вторых, гораздо более серьезная ситуация возникает в случае сбоя одного из процессов — при этом второй процесс оказывается заблокирован (при этом неважно, происходит ли сбой процесса в критическом разделе или нет).

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

 

/* процесс 0 */ /* процесс 1 */
while (turn! = 0) while (turn! = 1)
/* Ничего не делаем */; /* Ничего не делаем */;
/* Критический раздел */; /* Критический раздел */;
turn = 1; turn = 0;
(а) первая попытка
/* процесс 0 */ /* процесс 1 */
while (flag[1]) while (flag[0])
/* Ничего не делаем */; /* Ничего не делаем */;
flag[0] = true; flag[l] = true;
/* Критический раздел */; /* Критический раздел */;
flag[0] = false; flag[l] = false;
(б) вторая попытка
/* процесс 0 */ /* процесс 1 */
flag[0] = true; flag[1] = true;
while (flag[1]) while (flag[0])
/* Ничего не делаем */; /* Ничего не делаем */;
/* Критический раздел */; /* Критический раздел */;
flag[0] = false; flag[1] = false;
(в) третья попытка
/* процесс 0 */ /* процесс 1 */
flag[0] = true; flag[1] = true;
while (flag[1]) while(flag[0])
{ {
flag[0] = false; flag[1] = false;
/* Задержка */ /* задержка */
flag[0] = true; flag[1] = true;
} }
/* Критический раздел */; /* Критический раздел */;
flag[0] = false; flag[1] = false;
   
(г) четвертая попытка

Рис. Попытки взаимных исключений






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.