Відмінності між версіями «Потоки та нитки в Microsoft Windows»
Рядок 27: | Рядок 27: | ||
Таким чином, доцільне використання нитей може значно поліпшити продуктивність і зручність використання програм. | Таким чином, доцільне використання нитей може значно поліпшити продуктивність і зручність використання програм. | ||
На одному процесорі багатонитевість відбувається шляхом тимчасової активізації різних нитей. Таке перемикання відбувається досить часто, щоб користувач сприймав виконання нитей як одночасне. У багатопроцесорних і багатоядерних системах ниті можуть реально виконуватися одночасно, при цьому кожен процесор або ядро обробляє окрему нить (або кілька нитей). | На одному процесорі багатонитевість відбувається шляхом тимчасової активізації різних нитей. Таке перемикання відбувається досить часто, щоб користувач сприймав виконання нитей як одночасне. У багатопроцесорних і багатоядерних системах ниті можуть реально виконуватися одночасно, при цьому кожен процесор або ядро обробляє окрему нить (або кілька нитей). | ||
+ | |||
+ | '''Загальна характеристика нитей''' | ||
+ | Хоча в кожної ниті свій контекст виконання, кожна нить усередині одного процесу використовує його віртуальний адресний простір (а також інші ресурси, які належать процесу). Це означає, що всі ниті в процесі можуть записувати й зчитувати вміст пам'яті інших нитей цього процесу. Але ниті не можуть посилатися на адресний простір іншого процесу. Виняток може бути в ситуації, коли процес надає частину свого адресного простору як розділ загальної пам'яті через об'єкт «проектований файл» (file mapping object), або коли один із процесів має право на відкриття іншого процесу й використовує функції доступу до пам'яті між процесами. | ||
+ | За замовчуванням у ниті немає власного маркера доступу, але він може отримати його, і це дозволить йому підміняти контекст захисту іншого процесу. Нить містить такі важливі елементи: | ||
+ | завантажений для виконання код; | ||
+ | вміст набору регістрів процесора, що відображають стан процесора; | ||
+ | два стеки, один із яких використовується ниттю при виконанні в режимі ядра, а інший — у користувацькому режимі; | ||
+ | закриту область пам'яті, яку називають локальною пам'яттю ниті (thread-local storage, TLS); вона використовується підсистемами, бібліотеками виконавчих систем (run-time libraries) і DLL; | ||
+ | унікальний ідентифікатор ниті; | ||
+ | іноді ниті мають свій контекст захисту, який використовується багатонитевими серверними програмами, що підміняють контекст захисту клієнтів. |
Версія за 22:16, 14 квітня 2013
Нить (англ. thread) або повніше нить виконання (англ. thread of execution), часто застосовується потік (програмний потік) та англіцизм тред — в інформатиці так називається спосіб програми розщепити себе на дві чи більше одночасні (чи псевдо-одночасні) задачі. Реалізація нитей та процесів відрізняються в різних операційних системах, але загалом нить міститься всередині процесу і різні ниті одного процесу спільно розподіляють деякі ресурси, в той час як різні процеси ресурси не розподіляють. В системах з одним процесором багатонитевість реалізується загалом поділом часу виконання («кванти часу»), дуже подібно до паралельного виконання багатьох задач: процесор послідовно переключається між різними нитями. Це переключення контексту відбувається настільки швидко, що у кінцевого користувача створюється ілюзія одночасного виконання. На багатопроцесорних чи на багатоядерних системах робота нитей здійснюється справді одночасно, бо різні ниті і процеси виконуються буквально одночасно різними процесорами або ядрами процесора. Особливості квантування в опраційній системі Windows розглянуто у статті Квант (Windows). Багато сучасних операційних систем прямо підтримують квантування часу і багатопроцесорну роботу нитей через планувальник процесів. Ядро операційної системи дозволяє програмісту маніпулювати нитями через інтерфейс системних викликів. Деякі реалізації викликають ниті ядра, оскільки легковагові процеси (англ. lightweight process, LWP) є спеціальним типом нитей ядра, що розподіляють деякі стани і інформацію. Поза тим, програма може емулювати роботу нитей, використовуючи таймер, сигнали або інші методи, щоб перервати власне виконання і послідовно виконувати різні задачі власним квантуванням часу. Такий спосіб іноді зветься нитями користувацького простору (англ. user-space threads) або волокнами.
Порівняння нитей з процесами
Ниті відрізняються від традиційних процесів багатозадачних операційних систем, в тому що процеси: на загал, незалежні, дублюють значну частину інформації про стан, мають окремий адресний простір, взаємодіють тільки через системні міжпроцесорні механізми комунікацій. Ниті всередині процесу, з іншої сторони, розподіляють інформацію про стан процесу, і прямо доступаються до спільної пам'яті та інших ресурсів. Переключення контексту між нитями процеса на загал швидше, ніж переключення контексту між процесами. Описуючи ситуацію такі системи, як Windows NT та OS/2, кажуть, що мають «дешеві» ниті та «дорогі» процеси; в інших операційних системах ситуація не дуже відмінна.
Багатонитевість є популярною моделлю програмування і виконання, бо дозволяє багатьом нитям існувати всередині контексту одного процесу, розподіляючи ресурси процесу, але виконуючись незалежно. Нитева модель програмування забезпечує розробникам корисні абстракції для паралельного виконання. Проте, можливо найцікавіше застосування технології в випадку, коли один процес виконується на багатопроцесорній системі. Ця перевага багатонитевих програм дозволяє їм скоріше виконуватися на комп'ютерах з кількома процесорами, процесорами з кількома ядрами, або на кластері машин, бо ниті програми природно надають собі можливість справді паралельного виконання. У такому випадку програміст має бути особливо обережним, щоб уникнути стану гонитви та інших непередбачених поведінок. Для забезпечення коректної роботи з даними, ниті часто потребують процедури доступу до даних в певному порядку. Ниті також вимагають атомарних операцій (часто реалізованих з використанням семафорів), щоб уникнути одночасної неузгодженої модифікації даних або їхнього читання, в той час як процес модифікує дані. Недбале поводження з такими примітивами може призвести до взаємного блокування. Планувальники операційних систем переключають ниті одним з двох можливих способів. Запобіжна або витісняюча багатонитевість загалом розглядається як кращий підхід, бо вона дозволяє операційній системі визначити, коли може статися перемикання контексту. На противагу, кооперативна багатонитевість покладається на самі ниті, щоб вони передали контроль виконання на точках зупину. Це може створити проблеми, якщо нить чекає на ресурс, який став недоступним. Недолік запобіжної багатонитевості в тому, що перемикання контексту може статися в недоречну мить, спричиняючи пріоритетну інверсію або інші погані ефекти, яких можна уникнути в кооперативній багатонитевості. Традиційно базове комп'ютерне апаратне забезпечення не надавало багато підтримку багатонитевості, оскільки переключення між нитями загалом є вже скорішою процедурою порівняно з переключенням контексту процесів. Процесори вбудованих систем, що мають більші вимоги до поведінки в реальному часі, можуть мати апаратну підтримку багатонитевості зменшенням часу перемикання, можливо розміщуючи виділений блок регістрів для кожної ниті, замість того, щоб зберігати/читати загальні регістри. На кінці 1990-х стала відома ідея виконання інструкцій з різних нитей одночасно, це зветься одночасною багатонитевостю. Ця можливість була введена в процесорі Intel Pentium 4 під ім'ям Hyper-threading.
Переваги багатонитевості Багатонитевість програми створює підґрунтя для реалізації реальної багатозадачності — виконання кількох завдань одночасно (якщо обчислювальна система є багатопроцесорною), або «псевдоодночасно» («майже одночасно») на однопроцесорних системах. Наявність кількох нитей дозволяє: Оптимізувати організацію поведінки програми. Часто поведінка програми може бути організована у кілька незалежних паралельних алгоритмів, тоді їх можна винести в окремі ниті. При цьому їм можна задавати різний пріоритет виконання. Обходити критичні до часу операції. Якщо програма має лише одну нить, то вона повинна зупинити все виконання при очікуванні повільних операцій, таких як запис у файл чи відображення засобами мультимедіа. При цьому процесор перебуває у простої, поки ця операція не завершиться. Якщо застосунок складається з кількох нитей, він може продовжувати виконання в окремих нитях, коли одна нить очікуватиме на завершення повільної операції. Реалізувати багатопроцесорну обробку. Якщо система, у якій працює програма, є мультипроцесорною, то можна сповна скористатися наявними обчислювальними ресурсами і підвищити її ефективність використанням кількох нитей. При цьому різні ниті можуть виконуватися одночасно на різних процесорах. Таким чином, доцільне використання нитей може значно поліпшити продуктивність і зручність використання програм. На одному процесорі багатонитевість відбувається шляхом тимчасової активізації різних нитей. Таке перемикання відбувається досить часто, щоб користувач сприймав виконання нитей як одночасне. У багатопроцесорних і багатоядерних системах ниті можуть реально виконуватися одночасно, при цьому кожен процесор або ядро обробляє окрему нить (або кілька нитей).
Загальна характеристика нитей Хоча в кожної ниті свій контекст виконання, кожна нить усередині одного процесу використовує його віртуальний адресний простір (а також інші ресурси, які належать процесу). Це означає, що всі ниті в процесі можуть записувати й зчитувати вміст пам'яті інших нитей цього процесу. Але ниті не можуть посилатися на адресний простір іншого процесу. Виняток може бути в ситуації, коли процес надає частину свого адресного простору як розділ загальної пам'яті через об'єкт «проектований файл» (file mapping object), або коли один із процесів має право на відкриття іншого процесу й використовує функції доступу до пам'яті між процесами. За замовчуванням у ниті немає власного маркера доступу, але він може отримати його, і це дозволить йому підміняти контекст захисту іншого процесу. Нить містить такі важливі елементи: завантажений для виконання код; вміст набору регістрів процесора, що відображають стан процесора; два стеки, один із яких використовується ниттю при виконанні в режимі ядра, а інший — у користувацькому режимі; закриту область пам'яті, яку називають локальною пам'яттю ниті (thread-local storage, TLS); вона використовується підсистемами, бібліотеками виконавчих систем (run-time libraries) і DLL; унікальний ідентифікатор ниті; іноді ниті мають свій контекст захисту, який використовується багатонитевими серверними програмами, що підміняють контекст захисту клієнтів.