Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Лабораторна робота № 2. Розробка багатопотокових застосувань
Мета: Програмна реалізація багатопотокових застосувань в операційній системі Windows.
Завдання: 1. Вивчення теоретичного матеріалу з управління потоками. 2. Складання алгоритму програми. 3. Програмна реалізація.
Хід роботи: 1. Отримати у викладача власний варіант завдання, який передбачає розпаралелювання роботи на декілька потоків. 2. Використовуючи вивчені механізми, розробити програму, яка реалізовує отримане завдання. 3. Написати звіт.
Хід захисту: 1. Продемонструвати викладачеві програму, яка виконує декілька потоків. 2. Пояснити програмний код застосування.
У сучасних ОС користувачам пропонується декілька типів паралельної роботи, основними з яких є процеси і потоки. Процеси - це програми на етапі виконання. Потоки - це менша одиниця роботи. Проте з погляду розподілу ресурсів саме потоки є головними, бо їм, а не процесам надається на певний час центральний процесор для виконання якої-небудь роботи. Розглянемо декілька функцій WinAPI, які виконують деякі операції над потоками.
Функція CreateThread створює потік, для виконання усередині адресного простору викликаючого процесу.
HANDLE CreateThread( PSECURITY_ATTRIBUTES lpThreadAttributes, // атрибути захисту потоку DWORD dwStackSize, // початковий розмір стека потоку, в байтах PTHREAD_START_ROUTINE lpStartAddress, // покажчик на функцію потоку PVOID lpParameter, // параметр для нового потоку DWORD dwCreationFlags, // прапорці створення потоку PDWORD lpThreadId // покажчик на ідентифікатор потоку, який повертається );
При успішному завершенні функції повертається дескриптор нового потоку. При невдалому завершенні функції повертається NULL. Параметри: LpThreadAttributes - покажчик на структуру SECURITY_ATTRIBUTES, яка визначає, чи може повернений дескриптор бути успадкований дочірніми процесами. Якщо lpThreadAttributes NULL, то дескриптор не може бути успадкований. DwStackSize - визначає розмір, в байтах, стека для нового потоку. Якщо визначений 0, то розмір стека за замовчуванням дорівнює розміру стека породжуючого потоку. Стек розподіляється автоматично в просторі пам’яті процесу, і звільняється при завершенні потоку. LpStartAddress - початкова адреса нового потоку. Це зазвичай адреса функції, оголошеної з узгодженням про виклики WINAPI, яке приймає одиночний 32-розрядний покажчик як параметр і повертає 32-розрядний код завершення. Прототип: DWORD WINAPI ThreadFunc(LPVOID); LpParameter - визначає єдине 32-розрядне значення параметра, який передається потоку. DwCreationFlags - визначає додаткові прапорці, які управляють створенням потоку. Якщо прапорець визначений CREATE_SUSPENDED, то потік створюється в стані очікування, і не виконуватиметься, поки не буде викликана функція ResumeThread. Якщо це значення нуль, то потік виконується негайно після створення. LpThreadId - покажчик на 32-розрядну змінну, яка набуває значення ідентифікатора потоку Потік можна завершити примусово за допомогою виклику наступних функцій Win32 API:
VOID ExitThread( DWORD ExitCode); // код завершення потоку і VOID TerminateThread( HANDLE hThread, // потік, який потрібно завершити DWORD ExitCode // код завершення потоку );
Для прикладу приведений фрагмент програми, яка обчислює добуток всіх чисел від 1 до 100.
// Функція потоку DWORD WINAPI ThreadFuction (PVOID Parametr) { int dobut = 1; // результат добутку int ii, *kk; kk = (int *) Parametr; for (ii = *k; ii < (*kk) + 50; ii ++) dobut *= ii; return dobut; }
// код викликів функцій для створення потоків DWORD idThread; int k1 = 1; k2 = 51; HANDLE h1, h2;
// створюється два потоки в призупиненому стані h1 = CreateThread (NULL, 0, ThreadFunction, & k1, CREATE_SUSPENDED, & idThread); h2 = CreateThread (NULL, 0, ThreadFunction, & k2, CREATE_SUSPENDED, & idThread);
// Виконання потоків ResumeThread (h1); ResumeThread (h2);
У цьому коді зустрілася дуже корисна Win32 API функція ResumeThread, яка поновлює виконання призупиненого потоку та описана як
DWORD ResumeThread ( HANDLE hThread // потік, який потрібно відновити );
Якщо виклик цієї функції успішний, то повертається попереднє значення лічильника простоїв цього потоку, інакше - 0xFFFFFFFF. Виконання окремого потоку можна призупиняти кілька разів (таке саме число разів він повинен поновлюватися), а здійснюється це викликом функції SuspendThread, описана як
DWORD SuspendThread ( HANDLE hThread // потік, який вимагається призупинити );
Потік може повідомити ОС, щоб вона не виділяла йому процесор певний час, вказане в мілісекундах.
VOID Sleep (DWORD MilliSeconds);
В ОС Windows 2000/XP є також функція, яка знаходить і відкриває потік згідно ідентифікатора.
HANDLE OpenThread ( DWORD DesiredAccess, BOOL InheritHandle, DWORD dwThreadId );
Теоретичні відомості
|