Реферат: Паралельноє програмирование
static| void| WRITEY|()
{
while| (true|)
Console|.Write("y|у|");
}
У головному потоці створюється новий потік t, виконуючий метод, який безперервно друкує символ ‘ y’. Одночасно головний потік безперервно друкує символ ‘ x’.
CLR призначає кожному потоку свій стек, так що локальні змінні зберігаються окремо. У наступному прикладі ми визначаємо метод із локальною змінною, а потім виконуємо його одночасно в головномуі cтвореному потоках:
static| void| Main|()
{
new| Thread|(Go|).Start();
Go|(); }
static| void| Go|()
{
// Визначаємо і використовуємо локальну змінну 'cycles|'
for| (int| cycles| = 0; cycles| < 5; cycles++|)
Console|.Write('?');
}
Управління багатопоточністю здійснює планувальник потоків, цю функцію CLR| зазвичай|звично| делегує операційній системі. Планувальник потоків гарантує, що активним потокам виділяється відповідний час на виконання, а потоки, чекаючі або блоковані, наприклад|приміром|, на чеканні|очікуванні| ексклюзивного блокування, або призначеного для користувача введення – не споживають часу CPU|.
На однопроцесорних комп'ютерах планувальник потоків використовує квантування часу – швидке перемикання між виконанням кожного з активних потоків. Це наводить до непередбачуваної поведінки, як в найпершому прикладі, де кожна послідовність символів ‘ X’ і ‘ Y’ відповідає кванту часу, виділеному потоку. У WindowsXP типове значення кванта часу – десятки мілісекунд – вибрано як набагато більше, ніж витрати CPU на перемикання контексту між потоками (декілька мікросекунд).
На багатопроцесорних комп'ютерах багатопоточність реалізована як суміш квантування часу і справжнього паралелізму, коли різні потоки виконують код на різних CPU|. Необхідність квантування часу все одно залишається, оскільки|тому що| операційна система повинна обслуговувати як свої власні потоки, так і потоки інших застосувань.
Говорять, що потік витісняється, коли його виконання припиняється із-за зовнішніх чинників типа квантування часу. В більшості випадків потік не може контролювати, коли і де він буде витиснений.
Всі потоки одного застосування логічно містяться|утримуються| в межах процесу – модуля операційної системи, в якому виконується додаток|застосування|.
У деяких аспектах потоки і процеси схожі – наприклад, час розділяється між процесами, що виконуються на одному комп'ютері, так само, як між потоками одного C#-додатком|. Ключова|джерельна| відмінність полягає в тому, що процеси повністю|цілком| ізольовані один від одного. Потоки розділяють пам'ять з|із| іншими потоками цього ж застосування. Завдяки цьому один потік може поставляти дані у фоновому режимі, а інший – показувати ці дані у міру їх вступу|надходження|.
Типове застосування з багатопоточністю виконує тривалі обчислення у фоновому режимі. Головний потік продовжує виконання, тоді як робочий потік виконує фонове завдання. У додатках WindowsForms, коли головний потік зайнятий тривалими обчисленнями, він не може обробляти повідомлення клавіатури і миші, і додаток перестає відгукуватися. З цієї причини слід запускати що віднімають багато часу завдання в робочому потоці, навіть якщо головний потік в цей час демонструє користувачеві модальний діалог з написом “Працюю... Будь ласка, чекайте” , оскільки програма не може перейти до наступної операції, поки не закінчена поточна. Таке рішення гарантує, що додаток не буде помічений операційною системою як що “Не відповідає”. В разі|у разі| додатків|застосувань| без UI|, наприклад, служб Windows|, багатопоточність має сенс, якщо виконуване завдання|задача| може зайняти|позичати| багато часу, оскільки|тому що| потрібне чекання|очікування| відповіді від іншого комп'ютера (сервера додатків|застосувань|, сервера баз даних або клієнта). Запуск такого завдання|задачі| в окремому робочому потоці означає, що головний|чільний| потік негайно звільняється|визволяє| для інших завдань|задач|.
Інше вживання багатопоточність знаходить в методах, що виконують інтенсивні обчислення. Такі методи можуть виконуватися швидше на багатопроцесорних комп'ютерах, якщо робоче навантаження рознесене по декількох потоках (кількість процесорів можна отримати через властивість Environment .ProcessorCount ).
C#-додаток можна зробити багатопотоковим двома способами: або явно створюючи додаткові потоки і управляючи ними, або використовуючи можливості неявного створення потоків .NET Framework – BackgroundWorker , пул потоків, потоковий таймер, Remoting-сервер, Web-службы або додаток ASP.NET. У двох останніх випадках альтернативи багатопоточності не існує. Однопоточний web-сервер не просто поганий, він просто неможливий. На щастя, в разі серверів додатків, що не зберігають стан (stateless), багатопоточність реалізується зазвичай досить просто, складнощі можливі хіба що в синхронізації доступу до даних в статичних змінних.
Багатопоточність разом з|поряд з| перевагами має і свої недоліки|нестачі|. Саме головний|чільний| з|із| них – значне збільшення складності програм. Складність збільшують не додаткові потоки самі по собі, а необхідність організації їх взаємодії. Від того, наскільки ця взаємодія є навмисною|умисною|, залежить тривалість циклу розробки, а також кількість помилок, що спорадично виявляються і важковловимих, в програмі. Таким чином, потрібно або підтримувати дизайн взаємодії потоків простим, або не використовувати багатопоточність взагалі, якщо лише|тільки| ви не маєте протиприродної схильності до переписування і відладки коди.
Крім того, надмірне використання багатопоточності віднімає ресурси і час CPU на створення потоків і перемикання між потоками. Зокрема, коли використовуються операції чтения/записи на диск, швидшим може виявитися послідовне виконання завдань в одному або двох потоках, чим одночасне їх виконання в декількох потоках.
Створення|створіння| і запуск потоків С#