ݺߣ

ݺߣShare a Scribd company logo
Операційні
системи
Лекція 6
Керування процесами і потоками
– синхронізація
2/19Лекція 6
План лекції
 Проблема синхронізації
 Гонки (змагання)
 Критична секція
 Атомарні операції
 Блокування, змінна блокування
 Семафори
 Задача виробник-споживач
 Взаємні блокування
 М’ютекси, умовні змінні, монітори
3/19Лекція 6
Проблема синхронізації:
приклад
 Нехай 2 потоки TA і TB (різних користувачів) отримують доступ до
деякого спільного ресурсу (банківський рахунок) з метою внесення
змін
 На рахунку 100 у.о.
 Користувач А намагається зняти 50 у.о.
 Користувач В намагається покласти ще 100 у.о.
 Алгоритм роботи потоків: total_amount = total_amount + new_amount;
1. Зчитати значення total_amount ( var1 = total_amount )
2. Обчислити нове значення total_amount ( var1 = var1 + new_amount )
3. Записати нове значення total_amount ( total_amount = var1 )
 Послідовність подій:
1. ТА зчитав total_amount var1A = 100
2. ТА обчислив total_amount var1A = 100 – 50
3. ТА записав total_amount total_amount = 50
4. ТВ зчитав total_amount var1B = 50
5. ТВ обчислив total_amount var1B = 50 + 100
6. ТВ записав total_amount total_amount = 150
Все вірно
4/19Лекція 6
Проблема синхронізації:
приклад (продовження)
 Але результат може бути іншим!
 Послідовність подій 2:
1. ТА зчитав total_amount var1A = 100
2. ТА обчислив total_amount var1A = 100 – 50
3. ТВ зчитав total_amount var1B = 100
4. ТВ обчислив total_amount var1B = 100 + 100
5. ТВ записав total_amount total_amount = 200
6. ТА записав total_amount total_amount = 50
В результаті total_amount == 50 (втрачена покладена сума)
 Послідовність подій 3:
1. ТА зчитав total_amount var1A = 100
2. ТВ зчитав total_amount var1B = 100
3. ТВ обчислив total_amount var1B = 100 + 100
4. ТА обчислив total_amount var1A = 100 – 50
5. ТА записав total_amount total_amount = 50
6. ТВ записав total_amount total_amount = 200
В результаті total_amount == 200 (сума не знята)
5/19Лекція 6
Деякі означення
 Ситуація, коли 2 чи більше потоків обробляють
спільні поділювані дані, і кінцевий результат
залежить від співвідношення швидкостей потоків,
називається гонками або змаганням (race
condition)
 Критична секція (critical section) – частина
програми, в якій здійснюється доступ до
поділюваних даних або ресурсу
 Щоби виключити гонки, у критичній секції, пов'язаній з
певним ресурсом, повинно знаходитись не більше 1 потоку
 Атомарна операція – така послідовність дій, яка
гарантовано виконується від початку до кінця без
втручання інших потоків (тобто, є неподільною)
 Найпростіша реалізація – потік, що знаходиться у
критичній секції, забороняє усі переривання
 Це неприйнятно, оскільки внаслідок збою у критичній секції
уся система може залишитись у непрацездатному стані
6/19Лекція 6
Блокування
 Блокування (locks) – це механізм, який
не дозволяє більше як одному потокові
виконувати код критичної секції
 Найпростіша (наївна) реалізація
блокування – вводимо змінну блокування
F(D) (1 – вільно, 0 – зайнято)
 Алгоритм спін-блокування (spinlock)
 Здійснюємо опитування у циклі, доки не
виявимо, що ресурс вільний – так зване
активне очікування (busy waiting)
 Встановлюємо відповідне значення
змінної блокування і займаємо ресурс
 Проблема реалізації – операція
перевірка-встановлення має бути
атомарною (необхідна апаратна
підтримка)
 Суттєвий недолік алгоритму –
нераціональні витрати процесорного
часу
Ресурс
вільний,
F(D)==1?
Зайняти ресурс,
F(D)=0
ні
так
Критична секція
ресурсу D
Звільнити ресурс,
F(D)=1
7/19Лекція 6
Апарат подій для роботи
з критичними секціями
 Функція WAIT(D)
переводить потік у стан
очікування події звільнення
ресурсу D
 Функція POST(D)
викликається після
звільнення ресурсу D і
переводить усі потоки, що
його очікують, у стан
готовності (планувальник
обере один з них на
виконання)
 У POSIX – виклики sleep() і
wakeup()
 Проблема: накладні
витрати ОС на здійснення
викликів можуть
перевищити економію
(іноді активне очікування
раціональніше)
Критична секція
ресурсу D
Ресурс
вільний,
F(D)==1?
Зайняти ресурс,
F(D)=0
ні
так
Звільнити ресурс,
F(D)=1
Перевести потік
у стан очікування
ресурсу D
Перевести потік,
що очікує ресурс D,
у стан готовності
LeaveCriticalSection()
EnterCriticalSection()
8/19Лекція 6
Семафори
 Семафор (semaphore) – цілочисловий невід'ємний
лічильник (позначають S)
 Для семафора визначені дві атомарні операції
 V(S) {
S++;
if (waiting_threads()) POST(S);
}
 P(S) {
if (S > 0) S--;
else WAIT(S);
}
 Окремий випадок: якщо семафор може приймати
лише значення 0 і 1 (двійковий семафор), він
фактично є змінною блокування
 Семафор – універсальний засіб, що забезпечує як
взаємне виключення, так і очікування події
9/19Лекція 6
Задача виробник-споживач
 Потік-виробник створює об’єкти і поміщає їх у буфер.
Операція розміщення об'єкта не є атомарною
 Потік-споживач отримує об’єкти і видаляє їх з буфера.
Операція видалення об'єкта не є атомарною
 Буфер має фіксовану довжину N
 Вимоги:
1. Коли виробник або споживач працює з буфером, усі інші
потоки повинні чекати завершення цієї операції
2. Коли виробник має намір помістити об'єкт у буфер, а
буфер повний, він має чекати, поки в буфері звільниться
місце
3. Коли споживач має намір отримати об'єкт з буфера, а
буфер порожній, він має чекати, поки в буфері з'явиться
об'єкт
10/19Лекція 6
Рішення задачі
виробник-споживач
1. Організуємо критичну секцію для роботи з
буфером. Для цього використаємо двійковий
семафор lock
2. Для організації очікування виробника
впровадимо семафор empty, значення якого
дорівнює кількості вільних місць у буфері
 Виробник перед спробою додати об'єкт у буфер
зменшує цей семафор, а якщо той дорівнював 0 –
переходить у стан очікування
 Споживач після того, як забере об'єкт з буфера,
збільшує цей семафор, при цьому, можливо,
ініціюється пробудження виробника
11/19Лекція 6
Рішення задачі
виробник-споживач
3. Для організації очікування споживача
впровадимо семафор full, значення якого
дорівнює кількості зайнятих місць у буфері
 Споживач перед спробою забрати об'єкт з буфера
зменшує цей семафор, а якщо той дорівнював 0 –
переходить у стан очікування
 Виробник після того, як додасть об'єкт до буфера,
збільшує цей семафор, при цьому, можливо,
ініціюється пробудження споживача
12/19Лекція 6
Псевдокод рішення задачі
виробник-споживач
semaphore lock = 1, empty = n, full = 0; // на початку буфер порожній
void producer() {
while(1) { // працює постійно
item = produce_new_item(); // створюємо об'єкт
P(empty); // перевіряємо наявність місця
P(lock); // входимо у критичну секцію
add_to_buffer(item); // додаємо об'єкт до буфера
V(lock); // виходимо з критичної секції
V(full); // повідомляємо про новий об'єкт
}
}
void consumer() {
while(1) { // працює постійно
P(full); // перевіряємо наявність об'єкта
P(lock); // входимо у критичну секцію
item = get_from_buffer(); // забираємо об'єкт з буфера
V(lock); // виходимо з критичної секції
V(empty); // повідомляємо про вільне місце
consume_new_item(item); // споживаємо об'єкт
}
}
13/19Лекція 6
Проблема взаємних
блокувань
 Припустимо, у функції “виробник” ми поміняли місцями P(empty) і
P(lock):
void producer() {
while(1) { // працює постійно
item = produce_new_item(); // створюємо об'єкт
P(lock); // входимо у критичну секцію
P(empty); // перевіряємо наявність місця
add_to_buffer(item); // додаємо об'єкт до буфера
V(lock); // виходимо з критичної секції
V(full); // повідомляємо про новий об'єкт
}
}
 Перевірка умови з можливим очікуванням здійснюється всередині
критичної секції. Можлива така послідовність дій:
1. Виробник входить у критичну секцію, закриваючи семафор lock
2. Виробник перевіряє семафор empty і очікує на ньому (буфер повний)
3. Споживач намагається ввійти у критичну секцію і блокується на
семафорі lock
 Така ситуація називається взаємне блокування або тупик
(deadlock)
14/19Лекція 6
Типові причини виникнення
взаємних блокувань
 Необережне застосування семафорів. Найчастіше –
через застосування семафору всередині критичної секції
 див. приклад вище
 Необхідність різним потокам одночасно захоплювати
кілька ресурсів
 “Філософи, що обідають”
 Реальна ситуація (різна послідовність захоплення ресурсів):
Потік А Потік В
1 Захопити диск 1 Захопити принтер
2 Захопити принтер 2 Захопити диск
3 Звільнити диск 3 Звільнити диск
4 Звільнити принтер 4 Звільнити принтер
А1А2В1 (В очікує)А3А4В1В2В3В4 – успішно
А1В1В2 (В очікує)А2 (А очікує) – взаємне блокування
15/19Лекція 6
Шляхи вирішення проблеми
взаємних блокувань
 Запобігання взаємних блокувань
1. Запит ресурсів здійснюється у певній послідовності,
спільній для усіх потоків
2. Якщо один з потрібних ресурсів зайнятий, то потік має
звільнити усі ресурси, що йому необхідні одночасно, і
повторити спробу через деякий час
3. Потік запитує усі ресурси у центрального диспетчера і
очікує їх виділення.
 Розпізнання взаємних блокувань
 Існують формальні методи, які вимагають ведення
таблиць розподілу ресурсів і запитів до них
 Відновлення після взаємних блокувань
 Аварійне завершення усіх або деяких заблокованих
потоків
 “Відкіт” до контрольної точки
16/19Лекція 6
Спеціалізовані засоби синхронізації
низького рівня – м’ютекс
М’ютекс (mutex – від mutual exclusion)
призначений для взаємного виключення
 Має два стани: вільний і зайнятий
 Визначені дві атомарні операції: зайняти і звільнити
 На відміну від двійкового семафора, звільнити
м’ютекс може лише той потік, що його зайняв
(власник м’ютекса)
 У деяких реалізаціях існує третя операція –
спробувати зайняти м’ютекс
 Повторна спроба власника м’ютекса зайняти той
самий м’ютекс призводить до блокування
 Існують рекурсивні м’ютекси, які діють за принципом
семафора лише для свого власника
17/19Лекція 6
Спеціалізовані засоби синхронізації
низького рівня – умовна змінна
Умовна змінна призначена для очікування події
 Умовна змінна пов'язана з певним м’ютексом і
даними, які він захищає
 Визначені три операції:
 сигналізація (signal) – потік, що виконав дії з даними у
критичній секції, перевіряє, чи не очікують на умовній
змінній інші потоки, і якщо очікують – переводить один з
них у стан готовності (потік буде поновлено після
звільнення м’ютексу)
 широкомовна сигналізація (broadcast) – те ж, що й
сигналізація, але у стан готовності переводить усі потоки
 очікування (wait) – викликається, коли потік у критичній
секції не може продовжувати роботу через невиконання
певної умови
• м’ютекс звільняють і інші потоки можуть мати доступ до даних
• після того, як інший потік здійснив виклик signal або broadcast,
потік знову повертається до виконання
• потік захоплює м’ютекс і продовжує роботу в критичній секції
Операція очікування не атомарна
18/19Лекція 6
Особливості використання
умовних змінних
 Перед викликом wait() необхідно перевіряти умову в
циклі while()
while(! condition_expr) // вираз для умови
wait(condition, mutex);
 Умовні змінні використовуються лише всередині
критичних секцій, на відміну від семафорів,
використання яких всередині критичних секцій
призводить до блокування
 Умовні змінні не зберігають стану, на відміну від
семафорів, які зберігають стан
 Рекурсивні м’ютекси не можуть бути використані з
умовними змінними, оскільки рекурсивний м’ютекс
може не звільнитися разом із викликом wait()
(гарантоване взаємне блокування)
19/19Лекція 6
Монітор
 Монітор – це набір функцій, які використовують
один загальний м’ютекс і нуль або більше
умовних змінних для керування паралельним
доступом до спільно використовуваних даних
 Правила реалізації монітора:
 Під час входу в кожну функцію монітора слід займати
м’ютекс, під час виходу – звільняти
 Під час роботи з умовною змінною необхідно завжди
вказувати відповідний м’ютекс (для роботи з умовною
змінною м’ютекс повинен завжди бути зайнятий)
 Під час перевірки на виконання умови очікування
необхідно застосовувати цикл, а не умовний оператор

More Related Content

What's hot (20)

Linux kernel modules
Linux kernel modulesLinux kernel modules
Linux kernel modules
Dheryta Jaisinghani
Sistemas Operacionais Modernos - Gerenciamento de MemóriaSistemas Operacionais Modernos - Gerenciamento de Memória
Sistemas Operacionais Modernos - Gerenciamento de Memória
Wellington Oliveira
Sistemas Operacionais - Aula 08 (Sincronização e Comunicação entre Processos)Sistemas Operacionais - Aula 08 (Sincronização e Comunicação entre Processos)
Sistemas Operacionais - Aula 08 (Sincronização e Comunicação entre Processos)
Leinylson Fontinele
Cs8493 unit 5
Cs8493 unit 5Cs8493 unit 5
Cs8493 unit 5
Kathirvel Ayyaswamy
Bootloader and bootloading
Bootloader and bootloadingBootloader and bootloading
Bootloader and bootloading
Arpita Gupta
Windows Architecture
Windows ArchitectureWindows Architecture
Windows Architecture
Amrith Krishna
Monolithic kernel vs. Microkernel
Monolithic kernel vs. MicrokernelMonolithic kernel vs. Microkernel
Monolithic kernel vs. Microkernel
RQK Khan
Resumo de S.O.Resumo de S.O.
Resumo de S.O.
dannas_06
Kernel (computing)
Kernel (computing)Kernel (computing)
Kernel (computing)
Teja Bheemanapally
Unix
UnixUnix
Unix
Erm78
2009 1 - sistemas operacionais - aula 3 - processos2009 1 - sistemas operacionais - aula 3 - processos
2009 1 - sistemas operacionais - aula 3 - processos
Computação Depressão
Linux Memory Management
Linux Memory ManagementLinux Memory Management
Linux Memory Management
Suvendu Kumar Dash
Hacking QNX
Hacking QNXHacking QNX
Hacking QNX
ricardomcm
Free bsdFree bsd
Free bsd
Diana
NTFS file system
NTFS file systemNTFS file system
NTFS file system
Ravi Yasas
Chapter 7
Chapter 7Chapter 7
Chapter 7
talhashahid40
4 threads
4 threads4 threads
4 threads
Dr. Loganathan R
linux device driver
linux device driverlinux device driver
linux device driver
Rahul Batra
Process scheduling linux
Process scheduling linuxProcess scheduling linux
Process scheduling linux
Dr. C.V. Suresh Babu
Linux Kernel - Virtual File System
Linux Kernel - Virtual File SystemLinux Kernel - Virtual File System
Linux Kernel - Virtual File System
Adrian Huang
Sistemas Operacionais Modernos - Gerenciamento de MemóriaSistemas Operacionais Modernos - Gerenciamento de Memória
Sistemas Operacionais Modernos - Gerenciamento de Memória
Wellington Oliveira
Sistemas Operacionais - Aula 08 (Sincronização e Comunicação entre Processos)Sistemas Operacionais - Aula 08 (Sincronização e Comunicação entre Processos)
Sistemas Operacionais - Aula 08 (Sincronização e Comunicação entre Processos)
Leinylson Fontinele
Bootloader and bootloading
Bootloader and bootloadingBootloader and bootloading
Bootloader and bootloading
Arpita Gupta
Monolithic kernel vs. Microkernel
Monolithic kernel vs. MicrokernelMonolithic kernel vs. Microkernel
Monolithic kernel vs. Microkernel
RQK Khan
Resumo de S.O.Resumo de S.O.
Resumo de S.O.
dannas_06
2009 1 - sistemas operacionais - aula 3 - processos2009 1 - sistemas operacionais - aula 3 - processos
2009 1 - sistemas operacionais - aula 3 - processos
Computação Depressão
Free bsdFree bsd
Free bsd
Diana
Linux Kernel - Virtual File System
Linux Kernel - Virtual File SystemLinux Kernel - Virtual File System
Linux Kernel - Virtual File System
Adrian Huang

Viewers also liked (20)

SAMPAT
SAMPATSAMPAT
SAMPAT
Sampath Piriya
Eskiciler İkinci El Beyaz Eşya Alımı
Eskiciler İkinci El Beyaz Eşya Alımı  Eskiciler İkinci El Beyaz Eşya Alımı
Eskiciler İkinci El Beyaz Eşya Alımı
Eskici eşya alanlar
Vemma Premier club
 Vemma Premier club Vemma Premier club
Vemma Premier club
Abiodun Fawole
Scada functions
Scada functionsScada functions
Scada functions
Sundarapandy Pillai
Green Horizon Workshops
Green Horizon WorkshopsGreen Horizon Workshops
Green Horizon Workshops
asimco
BAKTERIOLOGI - SISTEM PERNAFASAN
BAKTERIOLOGI - SISTEM PERNAFASANBAKTERIOLOGI - SISTEM PERNAFASAN
BAKTERIOLOGI - SISTEM PERNAFASAN
Muhammad Nasrullah
Z13 update
Z13 updateZ13 update
Z13 update
Stig Quistgaard
CARDIAC ARREST - JANTUNG TERHENTI
CARDIAC ARREST - JANTUNG TERHENTICARDIAC ARREST - JANTUNG TERHENTI
CARDIAC ARREST - JANTUNG TERHENTI
Muhammad Nasrullah
Contrato de servicios slideshareContrato de servicios slideshare
Contrato de servicios slideshare
jegvastorga
Fabelaydiana analisisFabelaydiana analisis
Fabelaydiana analisis
ErnestoFabela1196
prescription errors raise concern over electronic records
 prescription errors raise concern over electronic records  prescription errors raise concern over electronic records
prescription errors raise concern over electronic records
libertyville
The little history of the pizza
The little history of the pizzaThe little history of the pizza
The little history of the pizza
rosavelayos
List of Abbreviations
List of AbbreviationsList of Abbreviations
List of Abbreviations
Delta Lacey
ASPEK HUKUM PRAKTIK KEPERAWATAN PROFESIONAL
ASPEK  HUKUM PRAKTIK KEPERAWATAN PROFESIONALASPEK  HUKUM PRAKTIK KEPERAWATAN PROFESIONAL
ASPEK HUKUM PRAKTIK KEPERAWATAN PROFESIONAL
pjj_kemenkes
KEGAGALAN JANTUNG KONGESTIF
KEGAGALAN JANTUNG KONGESTIFKEGAGALAN JANTUNG KONGESTIF
KEGAGALAN JANTUNG KONGESTIF
Muhammad Nasrullah
Social Sciences & Humanities Across the SC5 WP2016/17 – Paul Kilkenny
Social Sciences & Humanities Across the SC5 WP2016/17 – Paul KilkennySocial Sciences & Humanities Across the SC5 WP2016/17 – Paul Kilkenny
Social Sciences & Humanities Across the SC5 WP2016/17 – Paul Kilkenny
Environmental Protection Agency, Ireland
INTESTINAL OBSTRUCTION
INTESTINAL OBSTRUCTIONINTESTINAL OBSTRUCTION
INTESTINAL OBSTRUCTION
Muhammad Nasrullah
Criatividade e ruturasCriatividade e ruturas
Criatividade e ruturas
Ana Barreiros
Eskiciler İkinci El Beyaz Eşya Alımı
Eskiciler İkinci El Beyaz Eşya Alımı  Eskiciler İkinci El Beyaz Eşya Alımı
Eskiciler İkinci El Beyaz Eşya Alımı
Eskici eşya alanlar
Green Horizon Workshops
Green Horizon WorkshopsGreen Horizon Workshops
Green Horizon Workshops
asimco
Contrato de servicios slideshareContrato de servicios slideshare
Contrato de servicios slideshare
jegvastorga
Fabelaydiana analisisFabelaydiana analisis
Fabelaydiana analisis
ErnestoFabela1196
prescription errors raise concern over electronic records
 prescription errors raise concern over electronic records  prescription errors raise concern over electronic records
prescription errors raise concern over electronic records
libertyville
The little history of the pizza
The little history of the pizzaThe little history of the pizza
The little history of the pizza
rosavelayos
ASPEK HUKUM PRAKTIK KEPERAWATAN PROFESIONAL
ASPEK  HUKUM PRAKTIK KEPERAWATAN PROFESIONALASPEK  HUKUM PRAKTIK KEPERAWATAN PROFESIONAL
ASPEK HUKUM PRAKTIK KEPERAWATAN PROFESIONAL
pjj_kemenkes
Criatividade e ruturasCriatividade e ruturas
Criatividade e ruturas
Ana Barreiros

Лекція №6

  • 2. 2/19Лекція 6 План лекції  Проблема синхронізації  Гонки (змагання)  Критична секція  Атомарні операції  Блокування, змінна блокування  Семафори  Задача виробник-споживач  Взаємні блокування  М’ютекси, умовні змінні, монітори
  • 3. 3/19Лекція 6 Проблема синхронізації: приклад  Нехай 2 потоки TA і TB (різних користувачів) отримують доступ до деякого спільного ресурсу (банківський рахунок) з метою внесення змін  На рахунку 100 у.о.  Користувач А намагається зняти 50 у.о.  Користувач В намагається покласти ще 100 у.о.  Алгоритм роботи потоків: total_amount = total_amount + new_amount; 1. Зчитати значення total_amount ( var1 = total_amount ) 2. Обчислити нове значення total_amount ( var1 = var1 + new_amount ) 3. Записати нове значення total_amount ( total_amount = var1 )  Послідовність подій: 1. ТА зчитав total_amount var1A = 100 2. ТА обчислив total_amount var1A = 100 – 50 3. ТА записав total_amount total_amount = 50 4. ТВ зчитав total_amount var1B = 50 5. ТВ обчислив total_amount var1B = 50 + 100 6. ТВ записав total_amount total_amount = 150 Все вірно
  • 4. 4/19Лекція 6 Проблема синхронізації: приклад (продовження)  Але результат може бути іншим!  Послідовність подій 2: 1. ТА зчитав total_amount var1A = 100 2. ТА обчислив total_amount var1A = 100 – 50 3. ТВ зчитав total_amount var1B = 100 4. ТВ обчислив total_amount var1B = 100 + 100 5. ТВ записав total_amount total_amount = 200 6. ТА записав total_amount total_amount = 50 В результаті total_amount == 50 (втрачена покладена сума)  Послідовність подій 3: 1. ТА зчитав total_amount var1A = 100 2. ТВ зчитав total_amount var1B = 100 3. ТВ обчислив total_amount var1B = 100 + 100 4. ТА обчислив total_amount var1A = 100 – 50 5. ТА записав total_amount total_amount = 50 6. ТВ записав total_amount total_amount = 200 В результаті total_amount == 200 (сума не знята)
  • 5. 5/19Лекція 6 Деякі означення  Ситуація, коли 2 чи більше потоків обробляють спільні поділювані дані, і кінцевий результат залежить від співвідношення швидкостей потоків, називається гонками або змаганням (race condition)  Критична секція (critical section) – частина програми, в якій здійснюється доступ до поділюваних даних або ресурсу  Щоби виключити гонки, у критичній секції, пов'язаній з певним ресурсом, повинно знаходитись не більше 1 потоку  Атомарна операція – така послідовність дій, яка гарантовано виконується від початку до кінця без втручання інших потоків (тобто, є неподільною)  Найпростіша реалізація – потік, що знаходиться у критичній секції, забороняє усі переривання  Це неприйнятно, оскільки внаслідок збою у критичній секції уся система може залишитись у непрацездатному стані
  • 6. 6/19Лекція 6 Блокування  Блокування (locks) – це механізм, який не дозволяє більше як одному потокові виконувати код критичної секції  Найпростіша (наївна) реалізація блокування – вводимо змінну блокування F(D) (1 – вільно, 0 – зайнято)  Алгоритм спін-блокування (spinlock)  Здійснюємо опитування у циклі, доки не виявимо, що ресурс вільний – так зване активне очікування (busy waiting)  Встановлюємо відповідне значення змінної блокування і займаємо ресурс  Проблема реалізації – операція перевірка-встановлення має бути атомарною (необхідна апаратна підтримка)  Суттєвий недолік алгоритму – нераціональні витрати процесорного часу Ресурс вільний, F(D)==1? Зайняти ресурс, F(D)=0 ні так Критична секція ресурсу D Звільнити ресурс, F(D)=1
  • 7. 7/19Лекція 6 Апарат подій для роботи з критичними секціями  Функція WAIT(D) переводить потік у стан очікування події звільнення ресурсу D  Функція POST(D) викликається після звільнення ресурсу D і переводить усі потоки, що його очікують, у стан готовності (планувальник обере один з них на виконання)  У POSIX – виклики sleep() і wakeup()  Проблема: накладні витрати ОС на здійснення викликів можуть перевищити економію (іноді активне очікування раціональніше) Критична секція ресурсу D Ресурс вільний, F(D)==1? Зайняти ресурс, F(D)=0 ні так Звільнити ресурс, F(D)=1 Перевести потік у стан очікування ресурсу D Перевести потік, що очікує ресурс D, у стан готовності LeaveCriticalSection() EnterCriticalSection()
  • 8. 8/19Лекція 6 Семафори  Семафор (semaphore) – цілочисловий невід'ємний лічильник (позначають S)  Для семафора визначені дві атомарні операції  V(S) { S++; if (waiting_threads()) POST(S); }  P(S) { if (S > 0) S--; else WAIT(S); }  Окремий випадок: якщо семафор може приймати лише значення 0 і 1 (двійковий семафор), він фактично є змінною блокування  Семафор – універсальний засіб, що забезпечує як взаємне виключення, так і очікування події
  • 9. 9/19Лекція 6 Задача виробник-споживач  Потік-виробник створює об’єкти і поміщає їх у буфер. Операція розміщення об'єкта не є атомарною  Потік-споживач отримує об’єкти і видаляє їх з буфера. Операція видалення об'єкта не є атомарною  Буфер має фіксовану довжину N  Вимоги: 1. Коли виробник або споживач працює з буфером, усі інші потоки повинні чекати завершення цієї операції 2. Коли виробник має намір помістити об'єкт у буфер, а буфер повний, він має чекати, поки в буфері звільниться місце 3. Коли споживач має намір отримати об'єкт з буфера, а буфер порожній, він має чекати, поки в буфері з'явиться об'єкт
  • 10. 10/19Лекція 6 Рішення задачі виробник-споживач 1. Організуємо критичну секцію для роботи з буфером. Для цього використаємо двійковий семафор lock 2. Для організації очікування виробника впровадимо семафор empty, значення якого дорівнює кількості вільних місць у буфері  Виробник перед спробою додати об'єкт у буфер зменшує цей семафор, а якщо той дорівнював 0 – переходить у стан очікування  Споживач після того, як забере об'єкт з буфера, збільшує цей семафор, при цьому, можливо, ініціюється пробудження виробника
  • 11. 11/19Лекція 6 Рішення задачі виробник-споживач 3. Для організації очікування споживача впровадимо семафор full, значення якого дорівнює кількості зайнятих місць у буфері  Споживач перед спробою забрати об'єкт з буфера зменшує цей семафор, а якщо той дорівнював 0 – переходить у стан очікування  Виробник після того, як додасть об'єкт до буфера, збільшує цей семафор, при цьому, можливо, ініціюється пробудження споживача
  • 12. 12/19Лекція 6 Псевдокод рішення задачі виробник-споживач semaphore lock = 1, empty = n, full = 0; // на початку буфер порожній void producer() { while(1) { // працює постійно item = produce_new_item(); // створюємо об'єкт P(empty); // перевіряємо наявність місця P(lock); // входимо у критичну секцію add_to_buffer(item); // додаємо об'єкт до буфера V(lock); // виходимо з критичної секції V(full); // повідомляємо про новий об'єкт } } void consumer() { while(1) { // працює постійно P(full); // перевіряємо наявність об'єкта P(lock); // входимо у критичну секцію item = get_from_buffer(); // забираємо об'єкт з буфера V(lock); // виходимо з критичної секції V(empty); // повідомляємо про вільне місце consume_new_item(item); // споживаємо об'єкт } }
  • 13. 13/19Лекція 6 Проблема взаємних блокувань  Припустимо, у функції “виробник” ми поміняли місцями P(empty) і P(lock): void producer() { while(1) { // працює постійно item = produce_new_item(); // створюємо об'єкт P(lock); // входимо у критичну секцію P(empty); // перевіряємо наявність місця add_to_buffer(item); // додаємо об'єкт до буфера V(lock); // виходимо з критичної секції V(full); // повідомляємо про новий об'єкт } }  Перевірка умови з можливим очікуванням здійснюється всередині критичної секції. Можлива така послідовність дій: 1. Виробник входить у критичну секцію, закриваючи семафор lock 2. Виробник перевіряє семафор empty і очікує на ньому (буфер повний) 3. Споживач намагається ввійти у критичну секцію і блокується на семафорі lock  Така ситуація називається взаємне блокування або тупик (deadlock)
  • 14. 14/19Лекція 6 Типові причини виникнення взаємних блокувань  Необережне застосування семафорів. Найчастіше – через застосування семафору всередині критичної секції  див. приклад вище  Необхідність різним потокам одночасно захоплювати кілька ресурсів  “Філософи, що обідають”  Реальна ситуація (різна послідовність захоплення ресурсів): Потік А Потік В 1 Захопити диск 1 Захопити принтер 2 Захопити принтер 2 Захопити диск 3 Звільнити диск 3 Звільнити диск 4 Звільнити принтер 4 Звільнити принтер А1А2В1 (В очікує)А3А4В1В2В3В4 – успішно А1В1В2 (В очікує)А2 (А очікує) – взаємне блокування
  • 15. 15/19Лекція 6 Шляхи вирішення проблеми взаємних блокувань  Запобігання взаємних блокувань 1. Запит ресурсів здійснюється у певній послідовності, спільній для усіх потоків 2. Якщо один з потрібних ресурсів зайнятий, то потік має звільнити усі ресурси, що йому необхідні одночасно, і повторити спробу через деякий час 3. Потік запитує усі ресурси у центрального диспетчера і очікує їх виділення.  Розпізнання взаємних блокувань  Існують формальні методи, які вимагають ведення таблиць розподілу ресурсів і запитів до них  Відновлення після взаємних блокувань  Аварійне завершення усіх або деяких заблокованих потоків  “Відкіт” до контрольної точки
  • 16. 16/19Лекція 6 Спеціалізовані засоби синхронізації низького рівня – м’ютекс М’ютекс (mutex – від mutual exclusion) призначений для взаємного виключення  Має два стани: вільний і зайнятий  Визначені дві атомарні операції: зайняти і звільнити  На відміну від двійкового семафора, звільнити м’ютекс може лише той потік, що його зайняв (власник м’ютекса)  У деяких реалізаціях існує третя операція – спробувати зайняти м’ютекс  Повторна спроба власника м’ютекса зайняти той самий м’ютекс призводить до блокування  Існують рекурсивні м’ютекси, які діють за принципом семафора лише для свого власника
  • 17. 17/19Лекція 6 Спеціалізовані засоби синхронізації низького рівня – умовна змінна Умовна змінна призначена для очікування події  Умовна змінна пов'язана з певним м’ютексом і даними, які він захищає  Визначені три операції:  сигналізація (signal) – потік, що виконав дії з даними у критичній секції, перевіряє, чи не очікують на умовній змінній інші потоки, і якщо очікують – переводить один з них у стан готовності (потік буде поновлено після звільнення м’ютексу)  широкомовна сигналізація (broadcast) – те ж, що й сигналізація, але у стан готовності переводить усі потоки  очікування (wait) – викликається, коли потік у критичній секції не може продовжувати роботу через невиконання певної умови • м’ютекс звільняють і інші потоки можуть мати доступ до даних • після того, як інший потік здійснив виклик signal або broadcast, потік знову повертається до виконання • потік захоплює м’ютекс і продовжує роботу в критичній секції Операція очікування не атомарна
  • 18. 18/19Лекція 6 Особливості використання умовних змінних  Перед викликом wait() необхідно перевіряти умову в циклі while() while(! condition_expr) // вираз для умови wait(condition, mutex);  Умовні змінні використовуються лише всередині критичних секцій, на відміну від семафорів, використання яких всередині критичних секцій призводить до блокування  Умовні змінні не зберігають стану, на відміну від семафорів, які зберігають стан  Рекурсивні м’ютекси не можуть бути використані з умовними змінними, оскільки рекурсивний м’ютекс може не звільнитися разом із викликом wait() (гарантоване взаємне блокування)
  • 19. 19/19Лекція 6 Монітор  Монітор – це набір функцій, які використовують один загальний м’ютекс і нуль або більше умовних змінних для керування паралельним доступом до спільно використовуваних даних  Правила реалізації монітора:  Під час входу в кожну функцію монітора слід займати м’ютекс, під час виходу – звільняти  Під час роботи з умовною змінною необхідно завжди вказувати відповідний м’ютекс (для роботи з умовною змінною м’ютекс повинен завжди бути зайнятий)  Під час перевірки на виконання умови очікування необхідно застосовувати цикл, а не умовний оператор