Конфлікт (або конкуренція) потоків (ниток)— це ситуація під час роботи програми, коли різні нитки при доступі до спільного ресурсу порушують очікувану логіку виконання програми. При цьому, коли кожна з цих ниток виконуватиметься сама (тобто інші нитки відсутні), то порушення виконання програми не спостерігатиметься.
Складності використання кількох нитей у програмах
У зв’язку з тим, що Windows використовує витісняючу багатозадачність, при якій виконання будь-якої нитки може бути перерване в будь-який момент часу, доступ кількох ниток до однієї ділянки пам’яті процесу може спричинити суттєві проблеми. Справа у тому, що багато операцій при виконанні програми повинні бути атомарними, тобто неподільними: коли нитка виконує таку дію, інші нитки повинні бачити її або ще непочатою, або вже завершеною. Якщо нитки не синхронізовані, то всі операції аж до рівня процесорних інструкцій є неатомарні.
Приклад конфлікту ниток
Розглянемо найпростіший приклад збільшення спільної для кількох ниток змінної A (фрагмент програми подано мовою Delphi).
var A: integer; // Оголошення глобальної змінної .................... // Код нитки -------------------------------------- Inc(A);
Цей оператор (Inc) на асемблерному рівні транслюється у три різних дії для процесора (завантаження числа в регістр eax, його збільшення на 1, та збереження у змінній A). Оскільки перемикання ниток може відбутися в будь-який момент, у тому числі між згаданими процесорними інструкціями, це може привести до непередбачуваного значення змінної A.
Розглянемо дві нитки, які виконують наведений вище код (Inc(A)). За сприятливих обставин ніякого конфлікту може не відбутися, і результат буде очікуваним: значення A збільшиться на 2 (це ілюструє перший рисунок).
Проте перемикання ниток зручним для нас чином — випадковість. Все може бути по-іншому, і тоді змінна A збільшиться на 1 та міститиме невірний результат (другий рисунок). Таку ситуацію і називають конфліктом (або конкуренцією) ниток.
Може здатися, що подібні ситуації настільки рідкісні, що згаданим ефектом можна знехтувати. Проте це не так. Розглянемо три однакових нитки, кожна з яких здійснює циклічний інкремент спільної змінної A. Функція нитки може бути такою:
function ThreadFunc(Ptr: Pointer): LongInt; var I : integer; begin for I := 1 to 1000000 do begin // Якийсь код Inc(A); // Якийсь код end; end;
Логічно було б припустити, що після виконання всіх трьох ниток змінна A дорівнюватиме 3000000. Проте внаслідок згаданої конкуренції ниток це значення буде суттєво відрізнятися (на практиці, для системи на основі двоядерного процесора Intel Pentium Dual-Core з частотою 1.73ГГц результат коливається в межах 2600000 та 2800000).
Слід зауважити, що кількість помилок у підрахунку залежить від обсягу циклу у функції нитки: при малій кількості ітерацій вони всі можуть реалізуватися за один квант часу без перемикання ниток, і описаної помилки не виникне. В загальному можна констатувати, що чим більше часу займають операції зі спільною змінною, тим частішими будуть помилки. Тому значення змінної А з попереднього прикладу стає непередбачуване і може описуватися лише ймовірнісними категоріями.
На багатопроцесорній системі частота виникнення таких помилок ще вища, оскільки дві нитки можуть виконуватися паралельно. При цьому додатково може виникнути проблема доступу до однієї ділянки пам’яті, коли дві нитки одночасно спробують записати своє значення у змінну А.
Синхронізація ниток
Детальніше : Синхронізація
Практично в кожній багатонитевій програмі потрібно узгоджувати між собою роботу ниток. Такі дії називають синхронізацією ниток. Необхідність у цьому може виникнути при доступі до спільних змінних (як демонструє останній приклад). В іншому випадку нитка не повинна продовжувати роботу, поки інша нитка не досягне певного етапу свого виконання. Завжди потрібно бути впевненим, що кілька ниток одночасно не записують дані в одну і ту ж ділянку пам’яті.
Для запобігання помилкам, які можуть виникати при узгодженні роботи кількох ниток у Windows, використовують засоби синхронізації: критичні секції, м’ютекси, семафори та . Об’єкти синхронізації забезпечують доступ до системних ресурсів, які можуть перебувати під керуванням одного чи кількох процесів. Об’єкт синхронізації може перебувати у двох станах: сигнальному та несигнальному. Коли об’єкт перебуває у стані зайнятості, або несигнальному стані, очікуюча нитка не може працювати. Сигнальний стан об’єкта синхронізації дозволяє продовжити роботу нитки.
Для очікування на сигнальний стан об'єкта синхронізації використовують функції очікування. Функції очікування (синхронізації) — це набір функцій API, які зупиняють виконання нитки, доки не буде досягнуто заданих умов. Такі функції перевіряють стан об’єктів синхронізації, і якщо вони перебувають у сигнальному стані, робота нитки відновлюється. В іншому випадку функція призупинить нитку, постійно опитуючи об’єкт синхронізації, поки він не перейде у сигнальний стан або не закінчиться заданий час очікування.
Джерела
- Руссинович М. Внутреннее устройство Microsoft Windows : Windows Server 2003, Windows XP и Windows 2000. Мастер-класс / М.Руссинович, Д.Соломон ; пер. с англ. – 4-е изд. – М : Издательско-торговый дом "Русская редакция" ; СПб : Питер, 2005.
- Коноваленко І.В., Федорів П.С. Системне програмування у Windows з прикладами на Delphi, Т:ТНТУ.- 2012 [ 8 грудня 2012 у Wayback Machine.].
- Харт Джонсон М. Системное программирование в среде Windows / Джонсон М. Харт ; пер. с англ. – М. : Издательский дом "Вильямс", 2005. – 592с.
Дивись також
Це незавершена стаття про операційні системи. Ви можете проєкту, виправивши або дописавши її. |
Це незавершена стаття про програмування. Ви можете проєкту, виправивши або дописавши її. |
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Konflikt abo konkurenciya potokiv nitok ce situaciya pid chas roboti programi koli rizni nitki pri dostupi do spilnogo resursu porushuyut ochikuvanu logiku vikonannya programi Pri comu koli kozhna z cih nitok vikonuvatimetsya sama tobto inshi nitki vidsutni to porushennya vikonannya programi ne sposterigatimetsya Skladnosti vikoristannya kilkoh nitej u programahKozhna z nitej zbilshuye znachennya zminnoyi A na 1 i v rezultati otrimuyemo pravilne znachennya zminnoyi A 2 Kozhna z nitej zbilshuye znachennya zminnoyi A na 1 ale cherez peremikannya nitok u nespodivanij moment otrimuyemo neochikuvane znachennya zminnoyi A 1 U zv yazku z tim sho Windows vikoristovuye vitisnyayuchu bagatozadachnist pri yakij vikonannya bud yakoyi nitki mozhe buti perervane v bud yakij moment chasu dostup kilkoh nitok do odniyeyi dilyanki pam yati procesu mozhe sprichiniti suttyevi problemi Sprava u tomu sho bagato operacij pri vikonanni programi povinni buti atomarnimi tobto nepodilnimi koli nitka vikonuye taku diyu inshi nitki povinni bachiti yiyi abo she nepochatoyu abo vzhe zavershenoyu Yaksho nitki ne sinhronizovani to vsi operaciyi azh do rivnya procesornih instrukcij ye neatomarni Priklad konfliktu nitok Rozglyanemo najprostishij priklad zbilshennya spilnoyi dlya kilkoh nitok zminnoyi A fragment programi podano movoyu Delphi var A integer Ogoloshennya globalnoyi zminnoyi Kod nitki Inc A Cej operator Inc na asemblernomu rivni translyuyetsya u tri riznih diyi dlya procesora zavantazhennya chisla v registr eax jogo zbilshennya na 1 ta zberezhennya u zminnij A Oskilki peremikannya nitok mozhe vidbutisya v bud yakij moment u tomu chisli mizh zgadanimi procesornimi instrukciyami ce mozhe privesti do neperedbachuvanogo znachennya zminnoyi A Rozglyanemo dvi nitki yaki vikonuyut navedenij vishe kod Inc A Za spriyatlivih obstavin niyakogo konfliktu mozhe ne vidbutisya i rezultat bude ochikuvanim znachennya A zbilshitsya na 2 ce ilyustruye pershij risunok Prote peremikannya nitok zruchnim dlya nas chinom vipadkovist Vse mozhe buti po inshomu i todi zminna A zbilshitsya na 1 ta mistitime nevirnij rezultat drugij risunok Taku situaciyu i nazivayut konfliktom abo konkurenciyeyu nitok Mozhe zdatisya sho podibni situaciyi nastilki ridkisni sho zgadanim efektom mozhna znehtuvati Prote ce ne tak Rozglyanemo tri odnakovih nitki kozhna z yakih zdijsnyuye ciklichnij inkrement spilnoyi zminnoyi A Funkciya nitki mozhe buti takoyu function ThreadFunc Ptr Pointer LongInt var I integer begin for I 1 to 1000000 do begin Yakijs kod Inc A Yakijs kod end end Logichno bulo b pripustiti sho pislya vikonannya vsih troh nitok zminna A dorivnyuvatime 3000000 Prote vnaslidok zgadanoyi konkurenciyi nitok ce znachennya bude suttyevo vidriznyatisya na praktici dlya sistemi na osnovi dvoyadernogo procesora Intel Pentium Dual Core z chastotoyu 1 73GGc rezultat kolivayetsya v mezhah 2600000 ta 2800000 Slid zauvazhiti sho kilkist pomilok u pidrahunku zalezhit vid obsyagu ciklu u funkciyi nitki pri malij kilkosti iteracij voni vsi mozhut realizuvatisya za odin kvant chasu bez peremikannya nitok i opisanoyi pomilki ne vinikne V zagalnomu mozhna konstatuvati sho chim bilshe chasu zajmayut operaciyi zi spilnoyu zminnoyu tim chastishimi budut pomilki Tomu znachennya zminnoyi A z poperednogo prikladu staye neperedbachuvane i mozhe opisuvatisya lishe jmovirnisnimi kategoriyami Na bagatoprocesornij sistemi chastota viniknennya takih pomilok she visha oskilki dvi nitki mozhut vikonuvatisya paralelno Pri comu dodatkovo mozhe viniknuti problema dostupu do odniyeyi dilyanki pam yati koli dvi nitki odnochasno sprobuyut zapisati svoye znachennya u zminnu A Sinhronizaciya nitokDetalnishe Sinhronizaciya Praktichno v kozhnij bagatonitevij programi potribno uzgodzhuvati mizh soboyu robotu nitok Taki diyi nazivayut sinhronizaciyeyu nitok Neobhidnist u comu mozhe viniknuti pri dostupi do spilnih zminnih yak demonstruye ostannij priklad V inshomu vipadku nitka ne povinna prodovzhuvati robotu poki insha nitka ne dosyagne pevnogo etapu svogo vikonannya Zavzhdi potribno buti vpevnenim sho kilka nitok odnochasno ne zapisuyut dani v odnu i tu zh dilyanku pam yati Dlya zapobigannya pomilkam yaki mozhut vinikati pri uzgodzhenni roboti kilkoh nitok u Windows vikoristovuyut zasobi sinhronizaciyi kritichni sekciyi m yuteksi semafori ta Ob yekti sinhronizaciyi zabezpechuyut dostup do sistemnih resursiv yaki mozhut perebuvati pid keruvannyam odnogo chi kilkoh procesiv Ob yekt sinhronizaciyi mozhe perebuvati u dvoh stanah signalnomu ta nesignalnomu Koli ob yekt perebuvaye u stani zajnyatosti abo nesignalnomu stani ochikuyucha nitka ne mozhe pracyuvati Signalnij stan ob yekta sinhronizaciyi dozvolyaye prodovzhiti robotu nitki Dlya ochikuvannya na signalnij stan ob yekta sinhronizaciyi vikoristovuyut funkciyi ochikuvannya Funkciyi ochikuvannya sinhronizaciyi ce nabir funkcij API yaki zupinyayut vikonannya nitki doki ne bude dosyagnuto zadanih umov Taki funkciyi pereviryayut stan ob yektiv sinhronizaciyi i yaksho voni perebuvayut u signalnomu stani robota nitki vidnovlyuyetsya V inshomu vipadku funkciya prizupinit nitku postijno opituyuchi ob yekt sinhronizaciyi poki vin ne perejde u signalnij stan abo ne zakinchitsya zadanij chas ochikuvannya DzherelaRussinovich M Vnutrennee ustrojstvo Microsoft Windows Windows Server 2003 Windows XP i Windows 2000 Master klass M Russinovich D Solomon per s angl 4 e izd M Izdatelsko torgovyj dom Russkaya redakciya SPb Piter 2005 Konovalenko I V Fedoriv P S Sistemne programuvannya u Windows z prikladami na Delphi T TNTU 2012 8 grudnya 2012 u Wayback Machine Hart Dzhonson M Sistemnoe programmirovanie v srede Windows Dzhonson M Hart per s angl M Izdatelskij dom Vilyams 2005 592s Divis takozhBagatozadachnist Proces Kvant Windows Planuvannya nitej Ce nezavershena stattya pro operacijni sistemi Vi mozhete dopomogti proyektu vipravivshi abo dopisavshi yiyi Ce nezavershena stattya pro programuvannya Vi mozhete dopomogti proyektu vipravivshi abo dopisavshi yiyi