ПАРАЛЛЕЛЬНОЕ ПРОГРАММИРОВАНИЕ
26
Примитивы взаимоисключений
Алгоритм Деккера
Это программный вариант решения проблемы взаимного исключения.
Алгоритм учитывает следующие требования:
•
относительные скорости параллельных процессов могут быть любыми;
•
процессы вне критического участка не могут препятствовать другим про-
цессам входить в критический участок;
•
не должно быть бесконечного откладывания входа в критический участок.
enum state { UNLOCKED, LOCKED };
typedef struct {
char status[2]; /* байт статуса для каждого из двух процессов
*/
char turn; /* какой из процессов будет следующим */
} lock_t;
void init_lock(lock_t* lock) {
lock->status[0] =UNLOCKED;
lock->status[l] =UNLOCKED;
lock->turn = 0;
}
void lock(volatile lock_t* lock) {
/* устанавливаем блокировку для текущего процесса */
lock->status[cur_proc_id()) = LOCKED;
/* проверяем, не установлена ли блокировка другим процессом */
while ( lock->status[other_proc_id()] == LOCKED) {
/* если другой процесс уже установил блокировку, проверяем — чья
очередь войти в критический участок */
if ( lock->turn != cur_proc_id()) {
lock->status[cur_proc_id()] = UNLOCKED;
while ( lock->turn == other_proc_id());
lock->status[cur_proc_id()] = LOCKED; } } }
void unlock(lock_t* lock) {
lock->status[cur_proc_id()] = UNLOCKED; lock->turn = oth-
er_proc_id(); }
Крутящаяся блокировка
Крутящаяся блокировка
— механизм, реализующий взаимное исключение и
являющийся достаточно эффективным для коротких критических участков. Назва-
ние его вытекает из того факта, что процесс будет находиться в цикле, ожидая за-
вершение блокировки, установленной другим процессом.