:: Статистика ::

 
Індекс цитування

 

 

 

 

 

Примітиви синхронізації

  Я чую крик в темноті
Напевно, це сигнал.
В. Бутусов

Поглянувши на приклади 7.2 і 7.4, уважний читач повинен відзначити, що використовувана конструкція підозріло схожа на роботу із зовнішніми пристроями в режимі опиту. Дійсно, опит прапором змінному в циклі хоча і забезпечує гарантію того, що взаємовиключає, але володіє всіма недоліками, які ми вказували для опиту зовнішнього пристрою.
g випадку виконання паралельних ниток на одному процесорі, даний метод має ще один недолік: поки одна з ниток займається опитом, жодна інша нитка не може виконуватися, тому що процесор завантажений непродуктивною роботою.
Легко бачити, що в даному випадку використання переривань або якогось їх аналога проблеми не вирішить: в кращому разі, "переривання" викликатиметься не в тій нитці, в якій потрібно, зводячи завдання того, що взаємовиключає до попередньої, лише з вже новою змінною прапора, а в гіршому — приведе до виникнення ще однієї нитки. Завдання взаємодії між асинхронними нитками, таким чином, зводиться до вимоги того, аби нитки в якісь моменти переставали бути асинхронними, синхронизовались.
Якщо у нас вже є примітив взаємного виключення, ми можемо вирішити завдання синхронізації, надавши ще один примітив, який дозволяє активному процесу зупинитися, чекаючи, поки змінна прапора не набуде "правильного" значення, і продовжити виконання після цього. При обробці переривань роль такого примітиву може виконувати команда зупинки процесора: біля всіх сучасних процесорів переривання зупиняє "виконання" цієї команди, а повернення з обробника передає управління на наступну команду, таким чином виводячи процесор із сплячого стану. У багатопроцесорній конфігурації можна ввести засіб, за допомогою якого один процесор може викликати переривання іншого, — і тоді кожен з процесорів системи зможе чекати іншого, переходячи в режим сну. При реалізації ж многопоточностп на одному процесорі (див. разд. Витісняюча багатозадачність) примітив засипання (блокування) нитки повинен надаватися модулем, відповідальним за перемикання потоків.
Втім, якщо операції над прапором, засипання потоку і його пробудження реалізовані різними примітивами, ми ризикуємо отримати нову проблему (приклад 7.5). Вона полягає в тому, що якщо сигнал, що будить, поступить в проміжку між операторами testandset і pause ми його не отримаємо. В результаті операція pause приведе до засипання нашої нитки назавжди.

Приклад 7.5. Помилка втраченого пробудження (lost wake-up bug)

program пауза
var flag: Boolean;
procedure процесс1
var myflag: Boolean
while True do
begin
myflag := True;
testandset(myflag, flag);
if myflag then
(* Звернете увагу, що перевірка прапора *
* і засипання — це різні оператори! *)
pause;
критическаясекция();
flag := False;
end
end;

Одне з рішень полягає в ускладненні примітиву pause: він повинен засинати, якщо і лише якщо сигнал ще не приходив. Ускладнення виходить значне: мало того, що перед засипанням треба перевіряти нетривіальну умову, необхідно ще передбачити якийсь спосіб скидання цієї умови, якщо ми передбачаємо багатократне використання нашого примітиву.
Якщо писати на асемблері або родинних йому мовах, можна піти і витонченішим дорогою (приклад 7.6). Підміна адреси повернення в обробнику переривання гарантує нам, що якщо переривання по установці прапора станеться в проміжку між мітками label і ok ми перейдемо на мітку label і, замість того, щоб заснути навіки, благополучно перевіримо прапор і увійдемо до критичної секції.

Приклад 7.6. Обхід помилки втраченого пробудження

.globl flag
flag: db 0
jmpbuf: dw 0
proc flag_interrupt
push eax
tst jmpbuf
bz setflagonly
; підміняємо адресу повернення
move eax, jmpbuf
move sp[RETURN_ADDRESS_OFFSET], eax setflagonly
move eax, 1
move flag, eax
pop eax
iret endp
proc process!
inove eax, setjmp
move jmpbuf, eax setjmp:
move eax, 1
lock xchg eax, flag
tst eax
bz ok
halt
ok
xor eax, eax move jmpbuf, eax
критична секція
xor eax, eax move flag, eax
endp

Елегантніший і прийнятніший для мов високого рівня дорога вирішення цієї проблеми полягає в тому, аби об'єднати в атомарну операцію перевірку прапора і засипання. Нас з читачем можна привітати з винаходом двійкового семафора Дейкстри.

 

рекламодавці:

/ ml lfppюн Большой выбор домофонов Видеодомофон Commax CDV-50AM в Киеве

::  Меню ::

ГОЛОВНА

Введення

Представлення даних в обчислювальних системах 

Машинні мови

Завантаження програм 

Управління оперативною пам'яттю

Сегментна і сторінкова віртуальна пам'ять

Комп'ютер і зовнішні події

Паралелізм з точки зору програміста 

Реалізація багатозадачності на однопроцесорних комп'ютерах 

Зовнішні пристрої

Драйвери зовнішніх пристроїв 

Файлові системи 

Додаток. Огляд архітектури сучасних ОС

 


:: Навігація ::

Головна

Додати у вишукане  

 

 

 


Copyright © Asentli, 2008