Термінова допомога студентам
Дипломи, курсові, реферати, контрольні...

Теория багатозавдань і многопоточности

РефератДопомога в написанніДізнатися вартістьмоєї роботи

У РМ системи OS/2 будь-який потік може творити чергу повідомлень, або створювати. РМ-поток має чергу повідомлень, коли він збирається створювати вікно. З іншого боку, потік може створювати чергу повідомлень, коли він здійснює лише обробку даних чи графічний висновок. Оскільки потоки, не створюють черги повідомлень, не обробляють повідомлення, то не можуть призвести до «зависанню «системи… Читати ще >

Теория багатозавдань і многопоточности (реферат, курсова, диплом, контрольна)

До появи персональних комп’ютерів у світі існувало кілька технічних рішень дозволяють реалізувати многозадачность на великих машинах. У СРСР що це машини серії ЄС і болгарські ИЗОТ. Вони теоретично дозволяли підключати до 255 терміналів, де кожному терміналу виділялося певна кількість ресурсів комп’ютера та процесорного часу. Насправді нормальна праця такої комплексу забезпечувалася за наявності трохи більше 25−30 терміналів, менше при складних задачах.

Для персональних ЕОМ многозадачность не вводилася принципово. Адже з назви PC — «Personal Computer» передбачалося, що працювати буде одна людина з одного поточної завданням. Як ОС було прийнято оброблена система CP/M під назвою MS-DOS. Вона як і не передбачала багатозавдань. Основна проблема розробки многозадачной ОС це реентерабильность її функцій. Те є якщо одне процес запустив функцію читання файла, то інший процес не зможе як звертатися до файлам, а й викликати інші її функції. І тому необхідна підтримка лише на рівні процесора що була введена із розробкою лінійки 286.

Многозадачность і многопоточность 1.

Режими багатозавдань 2 Многозадачность в DOS 2 Невытесняющая многозадачность 3 Presentation Manager і послідовна чергу повідомлень 6 Рішення, використовують многопоточность 7 Многопоточная архітектура 9 Колізії, які під час використанні потоків 10 Переваги Windows 11 Нова вдосконалена многопоточная програма 13 Про використанні функції Sleep 13 Критичний розділ 14 Об'єкт Mutex 17 Повідомлення про події 18 Локальна пам’ять потоку 18.

Многозадачность і многопоточность.

Многозадачность (multitasking) — це здатність ОС виконувати кілька програм одночасно. У основі цього принципу лежить використання операційній системою апаратного таймера виділення термінів (time slices) кожного з одночасно виконуваних процесів. Якщо такі відтинки часу досить малі, й престижний автомобіль не перевантажена надто великою числом програм, то користувачеві здається, що всі ці програми виконуються параллельно.

Ідея багатозавдань не нова. Многозадачность реалізується великих комп’ютерах типу мэйнфрэйм (mainframe), яких підключені десятки, а часом і сотні, терміналів. Кожен користувача, сидячого за екраном такого термінала, складається враження, що вона має ексклюзивний доступ до всієї машині. З іншого боку, операційні системи мэйнфрэймов часто дають можливість користувачам перевести завдання фоновий режим, де їх виконуються тоді, як користувач може працювати з іншого программой.

А, щоб многозадачность стала реальністю на персональних комп’ютерах, знадобилося досить чимало часу. Але, здається, тепер ми наближаємося до епохи використання багатозавдань на ПК (PC). Як побачимо невдовзі, деякі розширені 16-разрядные версії Windows підтримують многозадачность, а наявні нині у нашому розпорядженні Windows NT і Windows 95 — 32-разрядные версії Windows, підтримують крім багатозавдань що й многопоточность (multithreading).

Многопоточность — це можливість програми самої бути многозадачной. Програма можна розділити деякі потоки виконання (threads), які, як здається, виконуються паралельно. На погляд ця концепція може бути чи корисною, але виявляється, що програми може використати многопоточность до виконання протяжних у часі операцій на фоновому режимі, не змушуючи користувача надовго відриватися від машины.

Режимы многозадачности.

Якось на зорі використання персональних комп’ютерів деякі відстоювали ідею багатозавдань майбутньої, але хто сушили голови питанням: яка користь від багатозавдань на однопользовательской машині? У дійсності виявилося, що многозадачность — те, що необхідно користувачам, навіть подозревавшим про этом.

Многозадачность в DOS.

Мікропроцесор Intel 8088, який використовували у перших ПК, ні спеціально розроблений для реалізації багатозавдань. Частково проблема (як було зазначено показано попередній главі) полягала у недоліках управління пам’яттю. Тоді, як безліч програм починає й ними закінчує своє виконання, многозадачная операційна система має здійснювати переміщення блоків пам’яті для об'єднання вільного простору. На процесорі 8088 це ставало неможливим реалізовувати стилі, прозорому для приложений.

Сама DOS не могла тут чимось істотно допомогти. Будучи розробленої в такий спосіб, щоб бути маленькій і заважати додатків, DOS підтримувала, крім завантаження програм, тож забезпечення ним доступу до файловій системі, ще дуже багато средств.

Проте, творчі програмісти, котрі з DOS біля підніжжя її появи, знайшли шлях подолання ці перепони, переважно при використанні резидентных (terminate-and-stay-resident, TSR) програм. Деякі TSR-программы, такі як спулер друку, використовували переривання апаратного таймера до виконання процесу у фоновому режимі. Інші, подібно всплывающим (popup) утилітам, таких як SideKick, могли виконувати одне з завдань перемикання — припинення виконання докладання тимчасово роботи утиліти. DOS також була вдосконалена задля забезпечення підтримки резидентных программ.

Деякі виробники програмного забезпечення намагалися створити многозадачные оболонки чи оболонки, використовують переключення між завданнями, як надбудови над DOS (наприклад, Quarterdeck «p.s DeskView), але одна з цих оболонок отримала стала вельми поширеною над ринком. Це, звісно. Windows.

Невытесняющая многозадачность.

Коли Microsoft випустила ринку Windows 1.0 в 1985 року, це були ще значною мірою штучним рішенням, вигаданим задля подолання обмежень MS DOS. Тоді Windows працював у реальному режимі (real mode), і навіть тоді Україна була здатна переміщати блоки фізичної пам’яті (одна з необхідних умов багатозавдань) і це, хоча й дуже прозоро для додатків, але ж цілком удовлетворительно.

У графічної віконною середовищі многозадачность набуває набагато більший сенс, ніж у однопользовательской операційній системі, використовує командний рядок. Наприклад, у «класичній операційній системі UNIX, яка з командної рядком, є можливість запускати програми з командної рядки те щоб вони виконувалися в фоновому режимі. Проте, будь-який висновок на екран з програми може бути переадресований в файл, інакше цей висновок змішається з поточним вмістом экрана.

Віконна оболонка дозволяє кільком програмам виконуватися спільно, поділяючи один екран. Перемикання уперед і тому стає тривіальним, є можливість швидко передавати дані з однієї програми до іншої, наприклад, розмістити картинку, створену у програмі малювання, в текстовому файлі, утвореному з допомогою текстового процесора. Передача даних підтримувалася у різних версіях Windows: спочатку з використанням папки обміну (clipboard), пізніше — через механізм динамічного обміну даними (Dynamic Data Exchange, DDE), зараз — через впровадження і зв’язування об'єктів (Object Linking and Embedding, OLE).

І все-таки, реалізована в ранніх версіях Windows многозадачность не була традиційної вытесняющей, заснованої на виділенні термінів, як і многопользовательских операційні системи. Такі операційні системи використовують системний таймер для періодичного переривання виконання одного завдання і запуску інший. 16-разрядные версії Windows підтримували так звану невытесняющую многозадачность (non-preemptive multitasking). Такий тип багатозавдань можливий завдяки заснованої повідомленнях архітектурі Windows. У випадку, Windows-программа лежить у пам’яті і виконувалася до того часу, доки отримувала повідомлення. Ці повідомлення часто були прямим чи опосередкованим результатом введення інформації користувачем з клавіатури чи миші. Після опрацювання повідомлення програма повертала управління назад Windows.

16-разрядные версії Windows або не мали можливості довільно переключати управління з одного Windows-программы в іншу, виходячи з кванти часу таймера. Перемикання між завданнями відбувався за момент, коли програма завершувала обробку повідомлення й повертала управління Windows. Таку невытесняющую многозадачность називають також кооперативної многозадачностью (cooperative multitasking) вона вимагає деякого узгодження між додатками. Одна Windows-программа могла паралізувати роботу всієї системи, коли їй вимагалося чимало часу для обробки сообщения.

Хоча невытесняющая многозадачность була основною типом багатозавдань в 16-разрядных версіях Windows, деякі елементи вытесняющей (примітивною, preemptive) багатозавдань у яких теж присутствовали.

Windows використовувала вытесняющую многозадачность до виконання DOSпрограм, і навіть дозволяла бібліотекам динамічної компонування (DLL) отримувати переривання апаратного таймера для завдань мультимедиа.

16-разрядные версії Windows мали деякі особливості, які допомагали програмістам, а то й дозволити, то крайнього заходу, справитися з обмеженнями, пов’язані з невытесняющей многозадачностью. Найбільш відомої є відображення курсору миші як клепсидри. Звісно, це розв’язання проблеми, лишень можливість дати знати користувачеві, що ваша програма зайнята виконанням протяжної у часі роботи, І що система що час буде недоступна. Іншим частковим рішенням є використання системного таймера Windows, що дозволяє виконувати якіабо дії періодично. Таймер часто використовують у додатках типу годинників та додатках, які працюють із анимацией.

Іншим рішенням із подолання обмежень невытесняющей багатозавдань є виклик функції PeekMessage, як ми вбачали у програмі RANDRECT у розділі 4. Зазвичай програма використовує виклик функції GetMes-sage для вилучення повідомлень з черги. Проте, тоді як даний час чергу повідомлень порожня, то функція GetMessage чекатиме надходження сполучення чергу, та був поверне його. Функція PeekMessage працює інакше — вона повертає управління програмі у тому разі, якщо ні повідомлень у черзі. Отже, виконання роботи, що вимагає великих витрат часу, триватиме доти, поки черги не з’являться повідомлення для даної будь-якої іншої программы.

Presentation Manager і послідовна чергу сообщений.

Першої спробою фірми Microsoft (спільно з IBM) впровадити многозадачность в квази-DOS/Windows оболонку була система OS/2 і Presentation Manager (PM). Хоча OS/2, звісно, підтримувала вытесняющую многозадачность, часто здавалося, що це витіснення був перенесено в PM. Річ у тім, що PM вибудовував у чергу повідомлення, формовані в результаті користувальницького введення від клавіатури чи миші. Це означає, що PM не надає програмі таке користувальницьке повідомлення до тих пір, поки попереднє повідомлення, запроваджене користувачем, нічого очікувати повністю обработано.

Хоча повідомлення від клавіатури чи миші - це частина безлічі повідомлень, що може отримати програма в PM чи Windows, більшість інших повідомлень результат подій, що з клавіатурою чи мишею. Наприклад, повідомлення від меню команд є наслідком вибору пункту меню з допомогою клавіатури чи миші. Повідомлення від клавіатури чи миші нічого очікувати оброблено до того часу, поки що не повністю оброблено повідомлення від меню.

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

Нині прийнято угоду у тому, що ні має бути змогу будь-якого одного докладання паралізувати роботу всієї системи, І що потрібно використовувати непослідовну чергу повідомлень, підтримувану системами Windows 95 і Windows NT. Якщо один програма зайнята виконанням протяжної у часі операції, що існує можливість переключити фокус введення інше приложение.

Решения, використовують многопоточность.

Вище розглянуто Presentation Manager ОС OS/2 тільки те, що це перша оболонка, яка підготувала свідомість деяких ветеранів програмування під Windows (зокрема і автора) до впровадження многопоточности. Цікаво, що обмежена підтримка многопоточности в РМ дала програмістам основну ідею організації програм, використовують многопоточность. Хоча ці обмеження зараз переважно подолані в Windows 95, тим щонайменше уроки, отримані під час роботи з більш обмеженими системами, залишаються актуальними і з цей день.

У многопоточной середовищі програми можна розділити на частини, звані потоками виконання (threads), які виконуються одночасно. Підтримка многопоточности виявляється найкращим рішенням проблеми послідовної черги повідомлень в РМ і їх отримує повний сенс у її реалізації в Windows 95.

У термінах програми «потік «- це функція, яка може також викликати інші функції програми. Програма починає виконуватися з його головного (первинного) потоку, що у традиційних програмах мовою З є функцією main, а Windows-программах — WinMain. Будучи виконуваної, функція може створювати нові потоки обробки, виконуючи системний виклик із зазначенням функції ініціалізації потоку (initial threading function). Операційна система в вытесняющем режимі переключає управління між потоками аналогічно, як це робить з процессами.

У РМ системи OS/2 будь-який потік може творити чергу повідомлень, або створювати. РМ-поток має чергу повідомлень, коли він збирається створювати вікно. З іншого боку, потік може створювати чергу повідомлень, коли він здійснює лише обробку даних чи графічний висновок. Оскільки потоки, не створюють черги повідомлень, не обробляють повідомлення, то не можуть призвести до «зависанню «системи. На потік, яка має черги повідомлень, накладається лише одне обмеження — вона може посилати асинхронне повідомлення вікно потоку, має чергу повідомлень, чи викликати якусь функцію, якщо це сприятиме посилці повідомлення. (Але ці потоки можуть посилати синхронні повідомлення потокам, у яких чергу сообщений.).

Отже, програмісти, котрі з РМ, навчилися розбивати свої програми однією потік з чергою повідомлень, створює всі вікна та обробний повідомлення їм, і тільки чи кілька потоків, які мають черг повідомлень, і виконують тривалі дії фоновому режимі. З іншого боку, програмісти, котрі з РМ, дізналися про «правилі 1/10 секунди ». Вона полягає у цьому, що потік з чергою повідомлень витрачає трохи більше 1/10 секунди на обробку будь-якого повідомлення. Усі, що потребує більшого часу, слід було виділяти в окремий потік. Якщо всі програмісти дотримувалися цього правила, то ніяка РМ-программа не могла викликати зависання системи понад 1/10 секунды.

Многопоточная архитектура.

Як уже відзначалося вище, обмеження РМ дали програмістам основні ідеї розуміння того, як застосовувати багато потоків у програмі, виконуваної в графічної середовищі. Нижче наведені наші рекомендації по архітектурі многопоточных програм: первинний чи головний (primary) потік вашої програми створює всі вікна й формує відповідні їм віконні процедури, замість необхідних у програмі і опрацьовує все повідомлення тих вікон. Усі інші потоки — це фонові завдання. Вони мають інтерактивною зв’язки Польщі з користувачем, інакше як через первинний поток.

Одне з способів досягти цього у тому, щоб первинний потік обробляв користувальницький введення й інші повідомлення, можливо створюючи при цьому вторинні (secondary) потоки у процесі. Ці вторинні потоки виконують які пов’язані з користувачем задачи.

Інакше кажучи, первинний потік вашої програми є губернатором, а вторинні потоки — почтом губернатора. Губернатор доручає всю велику роботу своїм помічникам у період, що він здійснює контакти з зовнішнім світом. Оскільки вторинні потоки належать до почту, вони можуть проводити свої прес-конференції. Вони скромно виконують кожен своє завдання, роблять звіт губернатора і чекають нових указаний.

Потоки всередині окремої програми є частинами процесу, тому поділяють все ресурси процесу, такі як пам’ять і відкриті файли. Оскільки потоки поділяють пам’ять, відведену програмі, всі вони поділяють і статичні перемінні. Проте, в кожного потоку є свій власний стік, і отже, автоматичні перемінні є унікальними кожному за потоку. Кожен потік, також, має стан процесора, яке зберігається відновлюється при переключенні між потоками.

Коллизии, які під час використанні потоков.

Власне розробка, програмування і налагодження складного многопоточного докладання є, природно, найскладнішими завданнями, із якими випадає зіштовхуватися програмісту для Windows. Бо у системі з вытесняющей многозадачностью потік то, можливо перерваний у будь-якій момент для переключення інший потік, вона може випадково статися будь-яке небажане взаємодія між двома потоками.

Однією з основних помилок в многопоточных програмах є так зване стан гонки (race condition). Це трапляється, якщо програміст вважає, що перший потік закінчить виконання своїх дій, наприклад, підготовку будь-яких даних, доти, щоб ці дані знадобляться іншому потоку. Для координації дій потоків операційним системам необхідні різноманітні форми синхронізації. Однією з цих форм є семафор (semaphore), що дозволяє програмісту призупинити виконання потоку у певній точці програми до того часу, що він не дістане від іншого потоку сигнал у тому, що може відновити роботу. Схожі на семафори критичні розділи (critical sections), які є розділи коду, під час виконання якого, потік не то, можливо прерван.

Але використання семафорів можуть призвести в іншу поширеної помилці, що з потоками, що називається тупиком (deadlock). Це може бути, коли два потоку блокують виконання одне одного, а того, щоб їх розблокувати необхідно продовжити работу.

На щастя, 32-разрядные програми стійкіші до визначених проблемам, включно з потоками, ніж 16-разрядные програми. Наприклад, припустимо, що перший потік виконує просте действие:

lCount++ ;

де ICount — 32-разрядная глобальна змінна типу довше ціле, використовувана іншими потоками. У 16-разрядной програмі, у якій такий оператор мови З транслюється на два інструкції машинного коду (спочатку инкрементируется молодші 16 розрядів, та був додається перенесення в старші 16 розрядів). Припустимо, що операційна система перервала потік між тими двома інструкціями машинного коду. Якщо змінна ICount мала значення $ 0000FFFF, то після виконання першої інструкції машинного коду ICount матиме нульовий значення. Якщо народних обранців станеться переривання потоку, то інший потік отримає нульовий значення перемінної ICount. Тільки по закінченні цього потоку значення ICount планується збільшити на одиницю до свого істинного значення $ 10 000.

Такі помилка може бути ніколи не виявлено, оскільки досить рідко призводить до проблемам під час виконання. Для 16-разрядных програм найкращий шлях запобігти таку помилку — це помістити цей вислів у критичний розділ, у якого потік може бути перерваний. У 32- розрядної програмі, проте, наведене вираз є цілком коректним, оскільки він компілюється до однієї інструкцію машинного кода.

Преимущества Windows.

Операційні системи Windows 95 і Windows NT немає послідовної черги повідомлень. Таке рішення видається дуже хорошим: якщо програма виконує тривалу обробку повідомлення, то курсор миші набуває форми клепсидри при розташуванні над вікном програмних засобів, змінюється на звичайну стрілку, коли він розташовується над вікном інший програми. Простим клацанням кнопкою миші можна перевести інше вікно на передній план.

Проте, користувач як і неспроможна працювати із фотографією, виконуючим тривалу операцію, оскільки виконання тривалої операції запобігає отримання повідомлень програмою. І це небажано. Програма мусить бути завжди відкрита для повідомлень, яка потребує використання вторинних потоков.

У Windows 95 і Windows NT немає різницю між потоками, мають чергу повідомлень, і потоками поза чергою повідомлень. Під час створення кожен потік отримує своє власне чергу повідомлень. Це знижує число обмежень, існуючих для потоків в РМ-программе. (Проте, в більшості випадків усі ще обробка введення і повідомлень ввозяться одному потоці, а довгі у часі завдання передаються іншим потокам, які створюють вікон.) Така схема організації докладання, як ми побачимо, майже завжди є найбільш разумной.

У Windows 95 і Windows NT є функція, що дозволяє одному потоку знищити інший потік, приналежний до того ж процесу. Як багато знайдете, коли почнете писати многопоточные додатка за Windows, іноді дуже зручно. Ранні версії ОС OS/2 не містили функції знищення потоков.

Windows 95 і Windows NT підтримують так звану локальну пам’ять потоку (thread local storage, TLS). Щоб зрозуміти, що це таке, пригадаємо у тому, що статичні перемінні, як глобальні і локальні стосовно функцій, поділяються між потоками, оскільки вони перебувають у зоні пам’яті даних процесу. Автоматичні перемінні (що є завжди локальними стосовно функції) — унікальні для кожного потоку, т. до. вони містяться у стеці, а кожен потік має власний стек.

Іноді буває зручно використовуватиме двох і більше потоків те ж функцію, а статичні дані використовувати унікальні кожному за потоку. Це і досвід використання локальної пам’яті потоку. Існує кілька викликів функцій Windows до роботи з локальної пам’яттю потоку. Фірма Microsoft запровадила розширення компілятор З, що дозволяє використовувати локальну пам’ять потоку прозорішим для програміста образом.

Новая вдосконалена многопоточная программа.

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

Є деякі ситуації, коли поява курсору миші як клепсидри, може цілком підхожим. Вище згадувалося «правило 1/10 секунди ». Отож, завантаження великого файла на згадку про може зажадати більше часу, ніж 1/10 секунди. Це означає, що функції завантаження файла повинні бути реалізовані з допомогою поділу на потоки? Зовсім необов’язково. Коли користувач дає програмі команду відкрити файл, він або він зазвичай хоче, щоб операційна система виконала її негайно. Виділення процесу завантаження файла в окремий потік просто призведе до ускладнення програми. Марно це робити навіть заради здобуття права похвалитися перед друзями, що ви пишіть многопоточные приложения.

О використанні функції Sleep.

Вище показано, як їм краще організувати архітектуру програми, використовує многопоточность, саме, щоб первинний потік створював все вікна у програмі, містив все віконні процедури цих вікон та обробляв все повідомлення. Побічні потоки виконують фонові завдання, чи завдання, довгі у времени.

Проте, припустимо, що потрібно реалізувати анімацію у вторинному потоці. Зазвичай анімація в Windows здійснюється з допомогою повідомлення WM_TIMER. Але якщо вторинний потік не створює вікно, він неспроможна отримати це повідомлення. Без завдання певного темпу анімація міг би здійснюватися занадто быстро.

Рішення полягає у використанні функції Sleep. Потік викликає функцію Sleep у тому, щоб добровільно відкласти своє виконання. Єдиний параметр цієї функції - час, задаваемое в миллисекундах. Функція Sleep не здійснює повернення до того часу, доки мине зазначений час. У протягом виконання потоку припиняється і виділення йому процесорного часу немає (хоча очевидно, що з потоку все-таки потрібна якась незначне час, протягом якого система повинна визначити, час відновлювати виконання потоку чи нет).

Якщо параметр функції Sleep заданий рівним нулю, то потік не матиме залишку виділеного йому кванта процесорного времени.

Коли натовп викликає функцію Sleep, затримка на заданий час належить до цього потоку. Система продовжує інші потоки цього та інших процессов Критический раздел.

У однозадачной операційній системі звичайні програми не потребують «світлофорах «для координації їх дій. Вони виконуються оскільки ніби є господарями дороги, через яку вони йдуть. Немає нічого, що могла б втрутитися у те, що делают.

Навіть у многозадачной операційній системі більшість програм виконуються незалежно друг від друга. Та деякі проблеми все-таки можуть виникнути. Наприклад, двох програмах може знадобитися читати і писати в один файл за одну і те час. Для таких випадків операційна система підтримує механізм поділу файлів (shared files) і блокування окремих фрагментів файла (record locking).

Проте, в операційній системі, підтримує многопоточность, таке рішення може зробити плутанину і створити потенційну небезпеку. Разделение.

даних між двома і більше потоками є спільною випадком. Наприклад, один потік може оновлювати одну або як змінних, а інший може використовувати ці перемінні. Іноді у цій ситуації може виникнути проблема, інколи ж — немає. (Пам'ятаєте, що операційна система може переключати управління потоками тільки між інструкціями машинного коду. Якщо просте ціла кількість поділяється між двома потоками, то зміна цієї перемінної зазвичай здійснюється однієї інструкцією машинного коду, і потенційні проблеми зводяться до минимуму.).

Проте, припустимо, що потоки поділяють кілька змінних чи структуру даних. Часто ці складні перемінні чи поля структур даних би мало бути узгодженими між собою. Операційна система може переривати потік у середині процесу відновлення цих змінних. У цьому вся разі потік, і потім використовує ці перемінні, матиме працювати з неузгодженими данными.

Через війну б виникла колізія, і легко уявити собі, як що така помилка можуть призвести до краху програми. У цій ситуації нам необхідно щось таке як світлофор, який міг би синхронізувати і координувати роботу потоків. Таким засобом і є критичний розділ. Критичний розділ — це блок коду, і під час якого потік може бути прерван.

Є чотири функції до роботи з критичними розділами. Щоб їх використовувати, вам необхідно визначити об'єкт типу критичний розділ, що є глобальної перемінної типу CRITICAL_SECTION. Наприклад, CRITICAL_SECTION CS ;

Тип даних CRITICAL_SECTION є структурою, та її поля задіяні лише всередині Windows. Об'єкт типу критичний розділ спочатку може бути инициализирован однією з потоків програми з допомогою функції: InitializeCriticalSection (&cs);

Ця функція створює об'єкт критичний розділ безпосередньо з ім'ям cs. У документації міститься таке попередження: «Об'єкт критичний розділ може бути переміщений чи скопійовано. Процес теж повинен модифікувати об'єкт, а повинен поводитися з нею, і з «чорним ящиком ». «.

Після ініціалізації об'єкта критичний розділ потік входить у критичний розділ, викликаючи функцію: EnterCriticalSection (&cs) ;

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

критичний розділ, буде затриманий всередині функції. Повернення з функції можливе лише тоді, коли перша потік залишить критичний розділ, викликавши функцію: LeaveCriticalSection (&cs);

Саме тоді другий потік, затриманий у функції EnterCriticalSection, стане власником критичного розділу, та її виконання буде возобновлено.

Коли об'єкт критичний розділ большє нє потрібен вашої програмі, його можна видалити з допомогою функції: DeleteCriticalSection (&cs);

Це спричинить різке до визволенню всіх ресурсів системи, задіяних для підтримки об'єкта критичний раздел.

Механізм критичних розділів грунтується на принципі взаємного винятку (mutual exclusion). Цей термін нас іще зустрінеться при подальшому розгляді синхронізації потоків. Лише одна потік то, можливо власником критичного розділу у кожний конкретний час. Отже, один потік може стати критичний розділ, встановити значення полів структури та вийти з критичного розділу. Інший потік, використовує цю структуру, також міг би ввійти у критичний розділ перед здійсненням доступу до полях структури, та був вийти з критичного раздела.

Зверніть увагу, що можна визначення кількох об'єктів типу критичний розділ, наприклад, cs1 і cs2. Якщо програмі є чотири потоку, і двоє перших їх поділяють деякі дані, вони можуть використовувати перший об'єкт критичний розділ, а через два інших потоку, також поділяючих інші дані, може використати другий об'єкт критичний раздел.

Зверніть увагу, що бути дуже обережним під час використання критичного розділу у головному потоці. Якщо вторинний потік проводить занадто чимало часу у його власному критичному розділі, це може призвести до «зависанню «головного потоку на занадто великий період времени.

Объект Mutex.

Існує одне обмеження використання критичних розділів. Воно у тому, що можна застосовувати для синхронізації потоків лише у межах процесу. Але бувають випадки, коли необхідно синхронізувати дії потоків різних процесів, котрі поділяють будь-які ресурси (наприклад, пам’ять). Використовувати критичні розділи в цій ситуації не можна. Натомість підключаються об'єкти типу mutex (mutex object).

Складене слово «mutex «відбувається з словосполучення «mutual exclusion », що означає взаємне виняток, і відбиває призначення. Ми ще хочемо унеможливити переривання потоку в програмі до того часу, поки що не виконано відновлення чи використання поділюваних данных.

Уведомления про событиях.

Ми можемо визначити поняття великої справи як дії, виконуючи які, програма порушить «правило 1/10 секунди ». Прикладами великої справи можуть бути: перевірка орфографії в текстових процесорах, сортування і індексування файлів баз даних, перерахунок електронної таблиці, печатку, і складна малювання. Звісно, як ми знаємо, найкраще вирішення полягає у дотриманні «правилу 1/10 секунди », т. е. у передачі великої справи вторинним потокам обробки. Ці вторинні потоки не створюють вікон та, отже, необмежені «правилом 1/10 секунди » .

Часто буває, що вторинному потоку треба проінформувати первинний потік у тому, що, а завершився, чи первинному потоку треба перервати роботу, виконувану вторинним потоком.

Локальная пам’ять потока.

Глобальні перемінні в многопоточных програмах (як і і кожна виділена пам’ять) поділяються між всіма потоками у програмі. Локальні статичні перемінні функцій також поділяються між всіма потоками, які цю функцію. Локальні автоматичні перемінні у функції є унікальними кожному за потоку, оскільки вони в стеці, а кожен потік має власний стек.

Може виникнути необхідність мати постійну область пам’яті, унікальну кожному за потоку. Наприклад, функція strtok мови З, яка вже згадувалася у цій главі, такої типу пам’ять. Поза сумнівом, що З їх підтримує. У Windows 95 є чотири функції, підтримують цю пам’ять, що називається локальної пам’яттю потоку (thread local storage, TLS).

Первинний потік викликає функцію JTsAlloc щоб одержати значення індексу: dwTlsIndex = TIsAlloc () ;

Він може зберігатися у глобальній перемінної чи може бути функції потоку в параметре-структуре.

Функція потоку починається з виділення пам’яті для структури даних, і з виклику функції TIsSetValue, використовуючи індекс, отриманий раніше: TIsSetValue (dwTlsIndex, GlobalAlloc (GPTR, sizeof (DATA))) ;

Це встановлює відповідність покажчика з конкретною потоком і конкретним індексом серед. Тепер, будь-яка функція, якій теж потрібне використовувати цей покажчик (включаючи саму базову функцію потоку), може використовувати код, такий такому: PDATA pdata; pdata = (PDATA) TIsGetValue (dwTlsIndex) ;

Тепер вони можуть змінювати значення pdata->a і pdata->b. Перед завершенням функції потоку слід звільнити захоплену пам’ять: GlobalFree (TIsGetValue (dwTlsIndex)) ;

Коли всі потоки, використовують ці дані буде завершено, первинний потік звільняє індекс: TIsFree (dwTlsIndex) ;

Корисно подивитися як організована локальна пам’ять потоку. (Мені невідомо, як насправді Windows 95 це робить, але описувана схема цілком правдоподібна.) По-перше, функція TIsAlloc міг би просто виділити блок пам’яті (довжиною 0 байт) й повернути значення індексу, який є покажчиком цей блок. Щоразу при виклик функції TIsSet Value з цим індексом блок пам’яті поповнюється 8 байт з допомогою функції GlobalReAlloc. У цих 8 байтах зберігаються ідентифікатор потоку, що викликає функцію, отриманий із допомогою функції GetCurrentThreadID, і покажчик, переданий функції TIsSetValue. Функція TIsGetValue просто використовує ідентифікатор потоку на допомогу пошуку в таблиці, та був повертає покажчик. Функція TZsFree звільняє блок памяти.

Реализация многопоточности в Delphi.

Стандартний майстер модулів в Delphi автоматично створює модуль у якому клас потоку із зазначеним ім'ям. Весь код що необхідно винести в окремий потік міститься у метод класу Execute.

Базовий клас до створення потоку користувача — TThread TThread = class protected procedure DoTerminate; virtual; procedure Execute; virtual; procedure Synchronize (Method: TThreadMethod); property ReturnValue: Integer; property Terminated: Boolean; public constructor Create (CreateSuspended: Boolean); procedure Resume; procedure Suspend; procedure Terminate; function WaitFor: LongWord; property FreeOnTerminate: Boolean; property Handle: Thandle; property Priority: TthreadPriority; property Suspended: Boolean; property ThreadID: Thandle; property OnTerminate: TnotifyEvent; end;

Процес, що породив потік може гнучко управляти його станом: пріоритетом Priority; призупинити і його виконання, а як і достроково завершити виконання потока.

Для виклику методів VCL необхідно синхронізувати дочірній потік з головним. І тому служить процедура Synchronize (Method:TThreadMethod);

unit Unit1; interface uses Classes; type TSamples = class (TThread) private.

{ Private declarations } protected procedure Execute; override; end;

implementation.

{ Підказка Delphi щодо Synchronize.

Important: Methods and properties of objects in VCL can only be used in a method called using Synchronize, for example,.

Synchronize (UpdateCaption);

and UpdateCaption could look like,.

procedure Samples. UpdateCaption; begin.

Form1.Caption := «Updated in a thread »; end; }.

{ Samples }.

procedure TSamples. Execute; begin { Тут має бути розміщений код потоку } end;

end.

Список використовуваної литературы.

1. Turbo Pascal for Windows в 2-х томах. Нейл Рубенкинг Пер. з анг. -.

М.:Мир, 1993, 536 з., ил.

2. Теорія і практика З++. Герберт Шилдт. перекл. з анг. — СПб.: BHV — Санкт;

Петербург, 1996. 416 з., ил.

3. Програмування для Windows 95; в 2-х томах. Чарльз Петзолд. перекл. з анг. — СПб.: BHV — Санкт-Петербург, 1997.- 752 з., ил.

4. Мікропроцесори 80×86 Архітектура, функціонування. В. М. Михальчук.

А.А.Ровдо С. В. Рыжиков Мн.: Битрикс, 1994. — 400с.

В роботі було розглянуто основні засади багатозавдань і многопоточности. Наведено приклади оформлення многопоточных додатків на Delphi. Надалі многозадачная технологія набуде додаткового розвиток. У цьому що вийшов релізі Windows під назвою Windows2000 для підтримки багатозавдань використовуються звані объекты-задания симетрично распределяющиеся між процесорами. Для прискорення роботи потужних серверних систем використовують машини з урахуванням 2,4 і навіть 8 процесорах. Таке серверне програмне забезпечення як Windows NT4.0, Unix, Linux так ж підтримує SMP — симметричную мультипроцессорную обробку даних. Робота таких систем була б неможливою без використання алгоритмів багатозавдань і многопоточности.

Показати весь текст
Заповнити форму поточною роботою