Контрольна робота
з інформатики
Особливості багатозадачності в середовіщі Windows
Вступ
Основні Поняття багатозадачності в Windows 95 - процес (задача) i Потік (нитка). Під процесом розуміється виконан прогрійте в цілому (WinWord, Excel, Visual C + + и т.д.) Потоками у свою Черга є частина процесу, Що виконують паралельно.
процесов Звичайний назівають екземпляр прогрів, Що віконується.
Хоча на Перший погляд Здається, Що программа и процес Поняття практично однакові, смороду фундаментально відрізняються один від одного. Програма представляє собою статичність набор команд, а процес Це набор ресурсів и даніх, Що вікорістовуються при віконанні прогр. Процес в Windows Складається з Наступний компонентів:
- Структура даніх, Що включає в себе всю інформацію про процес, в тому чіслі список відкрітіх дескріпторів різніх системних ресурсів, унікальній ідентіфікатор процесу, різноманітну Статистичнй інформацію и т.д.;
- Адресна простір - діапазон адресів віртуальної пам'яті, Якиме Може корістуватіся процес;
- Програма, Що віконується и дані, Що проектуються на віртуальній адресної простір процесу.
Будь Який процес має хоча б один Потік (у цьому випадка Його можна ототожніті з потоком). Це первинний Потік створюється системою автоматично при створенні процесу. Далі цею Потік Може породіті Інші потоки, ті в свою Черга Нові и т.д. Таким чином, один процес Може володіті декількома потоками, и тоді смороду одночасно виконують код в адресному просторі процесу.
Windows кращє Всього працює, коли ВСІ потоки можут займатіся Своїм ділом, не взаємодіючі Один з одним. Альо така Ситуація Дуже рідкісна. Звичайний Потік створюється для виконан певної роботи, про завершення якої, ймовірно, захочу узнаті Інший Потік.
Приклад: один Потік підготовляє дані, Інший їх сортує, а Третій віводіть результат у файл. Передає готові дані іншому потоку на сортування, Перший почінає Обробка нового блоку. Тім годиною другий Потік повідомляє третьому, Що можна віводіті результати. Роботу ціх трьох потоків необхідно сінхронізуваті.
Всі потоки в сістемі повінні мати доступ до системних ресурсів - купах, послідовнім портам, файлам, вікнам и т д. ЯКЩО Один із потоків запросити монопольний доступ до Якого-небудь ресурсу, іншім потокам, Якиме теж потрібен цею ресурс, не вдасться віконаті Свої Задачі. А з Другої стороні, просто неприпустимо, щоб потоки безконтрольного корістувалісь ресурсами. Інакше Може статися так, Що один Потік пише в блок пам'яті, з Якого Інший Щось зчітує.
Потоки повінні взаємодіяті Один з одним в двох основних випадка:
1) спільно вікорістовуючі один и тієї ж ресурс (щоб НЕ розрушіті Його);
2) коли треба повідоміті Інші потоки про завершення яких-небудь операцій
В Windows є маса засобів, Що спрощують сінхронізацію потоків. Альо точно спрогнозуваті, в Який момент потоки будуть робіті те і те, надзвичайно доладно.
Механізмі сінхронізації
Найбільш пробачимо механізмом сінхронізації є Використання Interlocked-функцій. Використання ціх функцій гарантує "атомарна" виконан потрібніх операцій, тобто потоки не будуть заважаті один одному.
Пояснімо на прікладі:
// definition of global viriable lorig g_x = 0;
DWORD WINAPI ThreadFunc1 (PVOID pvParam) {
g_x + +;
return (0); }
DWORD WINAPI ThreadFunc2 (PVOID pvParam} {
g_x + +;
return (0); }
Нема Ні якої впевненості, Що отрімаємо двійку, ТОМУ ЩО мі не управляємо механізмом вітіснення потоків.
// definition of global viriable long g_x = 0;
DWORD WINAPI ThreadFunc1 (PVOID pvParam) {
InterlockedExchangeAdd (& g_x, 1);
return (0); }
DWORD WINAPI ThreadFunc2 (PVOID pvPararr) {
InterlockedExchangeAdd (& g_x, 1);
return (0); }
Тут Вже можна буті Впевнений, Що Значення g_x = 2.
Розглянемо ці функції більш детально
ЯКЩО кілька потоків мают доступ до однієї змінного, ті Немає ніякої Гарантії, Що в процесі Зміни Значення цієї змінній одним потоком не відбудеться перемикання на Інший Потік, Що Може читать по її значення. Інший Потік у цьому випадка одержимий невірну інформацію. Для Запобігання таких конфліктів у Windows 95 Уведення ряд функцій, Що дозволяють коректно змінюваті змінні, доступ до якіх мают кілька потоків. Перелічімо функції, Що охороняють від перемикання Під годину Зміни Значення змінної:
LONG InterlockedIncrement (LPLONG lpAddend) - збільшує значення за адресою lpAddend на одиницю;
LONG InterlockedDecrement (LPLONG lpAddend) - зменшує значення за адресою lpAddend на одиницю;
LONG InterlockedExchange (LPLONG Target, LONG Value) - заміняє значення, Що знаходится за адресою Target, на значення, переданого в параметрі Value;
LONG InterlockedExchangeAdd (PLONG Addend, LONG Increment) - додає до значення за адресою Addend Значення Increment;
PVOID InterlockedCompareExchange (PVOID * Destination, PVOID Exchange, PVOID Comperand) - порівнює значення за адресою Destination Зі значенням, надіс у параметрі Comperand, и ЯКЩО ці Значення рівні, то за адресою Destination містіться значення, переданого в параметрі Exchange.
Іншімі словами, ЯКЩО в тексті Програми є загальна змінна, ті її Зміна винна віроблятіся в такий спосіб:
{long Val;
....
Val + +;// Неправильно
InterlockedIncrement (& Val);// Правильно
...
}
Усі Спроба Зробити Щось, Що вімагає моментальної реакції на Зовнішні Події, у середовіщі Windows 3.x приводили до більш Ніж скромно результатів, ТОМУ ЩО подібні Програми здобувана відносно стандартизованность, альо неповороткій графічний інтерфейс, и Більше нічого. Windows 95 у прінціпі дозволяє розробляті Критичність Вчасно реакції ПО типом систем Керування.
Цей метод хороший для Дуже простих речей, для більш складної сінхронізації ВІН НЕ Допоможи. На щастя у Windows передбачена п'ять стандартних механізмів для сінхронізації процесів и потоків:
семафор
критична Секція
м'ютекс
подія
таймер
Розглянемо Кожній з ціх механізмів.
критичності Секція
критичності Секція - ції частина коду, доступ до Якого тепер має Тільки один Потік. Інший Потік Може звернута до критичного розділу, Тільки коли Перший Вийди з нього.
Для роботи з критичними секціямі вікорістовуються наступні функції:
VOID InitializeCriticalSection (LPCRITICAL_SECTION lpCriticalSection) - ініціалізація сінхронізатора типу критичний Розділ.
lpCriticalSection - Покажчик на змінну типу CRITICAL_SECTION.
VOID EnterCriticalSection (LPCRITICAL_SECTION lpCriticalSection) - запит на вхід у Критичність секцію (Розділ)
lpCriticalSection - Покажчик на змінну типу CRITICAL_SECTION.
VOID LeaveCriticalSection (LPCRITICAL_SECTION lpCriticalSection) - вихід Із критичного розділу (Звільнення семафора).
lpCriticalSection - Покажчик на змінну типу CRITICAL_SECTION.
VOID DeleteCriticalSection (LPCRITICAL_SECTION lpCriticalSection) - відалення критичного розділу (звичайна при віході з прогрів).
lpCriticalSection - Покажчик на змінну типу CRITICAL_SECTION.
Отже, для Створення критичного розділу необхідно ініціалізуваті структуру CRITICAL_SECTION. Що Windows у Цій структурі зберігає, нас не стосується - Важливим, Що Покажчик на Цю структуру ідентіфікує наш семафор.
створі об'єкт CRITICAL_SECTION, ми можемо працюваті з ним, тобто Можемо позначіті код, доступ до Якого для одночасно виконують завдань потрібно сінхронізуваті.
Розглянемо такий приклад. Мі хочем запісуваті и зчітуваті Значення з Деяк глобального масивов mas. Причому записи и зчітування повінні віроблятіся двом...