
- •Урок № 61
- •Урок № 62
- •Урок № 72
- •Урок № 73
- •Створення зв'язку з файлом /dev/modem за допомогою команди lisa.
- •Настройка системи Linux для встановлення зв'язку.
- •Як створюється зв'язок з файлом /dev/modem за допомогою команди lisa?
- •Яким чином можна настроїти систему Linux для встановлення зв'язку?
- •Урок № 74
- •Урок № 75
- •Використання програми mail.
- •Урок № 76
- •Використання клієнта kpackage
- •Як використовується клієнт kpackage?
- •Урок № 77
- •Урок № 80
- •Урок № 82
- •Урок № 84
- •Урок № 85
- •Урок № 86
- •Урок № 87
- •Урок № 88
- •Урок № 89
- •Урок № 90
- •Урок № 92
- •Урок № 93
- •Урок № 95
- •Урок № 96
- •Урок № 97
- •Урок № 97
Урок № 90
(згідно навчальної робочої програми)
Тема: «Керування потоками у Windows ХР»
Питання:
Складові елементи потоку.
Структури даних потоку.
Створення потоків.
Особливості програмного інтерфейсу потоків.
Для того щоб виконувати код, у рамках процесу обов’язково необхідно створити потік. Процеси і потоки є різними сутностями в системі, що перебувають у чітко визначеному взаємозв’язку один з одним; для роботи з ними використовують різні системні виклики.
БагатопотоковістьWindowsХР базується на схемі 1:1. Кожному потоку користувача відповідає сутність у ядрі, при цьому ядро відповідає за планування потоків. Процеси не плануються.
Складові елементи потоку
Потік у WindowsХР складається з таких елементів:
вмісту набору регістрів, який визначає стан процесора;
двох стеків — один використовують для роботи в режимі користувача, інший — у режимі ядра; ці стеки розміщені в адресному просторі процесу, що створив цей потік;
локальної пам’яті потоку (TLS);
унікального ідентифікатора потоку (threadid, tid), який вибирають із того самого простору імен, що й ідентифікатори процесів.
Сукупність стану процесора, стеків і локальної пам’яті потоку становить контекст потоку. Кожний потік має власний контекст. Усі інші ресурси процесу спільно використовуються потоками.
Розрізняють два види потоків: потоки користувача і потоки ядра, які у Windows ХР називають системними робочими потоками — system worker threads. Перші з них створюють у режимі користувача й тільки за необхідності перемикають у режим ядра. Інші створюють в ядрі під час його ініціалізації і виконують у режимі ядра протягом усього часу їхнього існування.
Структури даних потоку
Для виконавчої системи WindowsХР кожен потік відображається об’єктом-потоком виконавчої системи(executivethreadobject), який також називають керуючим блоком потоку(executivethreadblock, ETHREAD). Для ядра системи потік відображається об’єктом-потоком ядра (kernelthreadobject), який також називають блоком потоку ядра(threadkernelblock, KTHREAD).
У режимі користувача доступним є блок оточення потоку(threadenvironmentblock, ТЕВ), який перебуває в адресному просторі процесу, що створив потік.
Неважко помітити, що кожній структурі даних потоку відповідає структура даних процесу (блоки EPROCESS, KPR0CESSі РЕВ).
Керуючий блок потоку містить базову інформацію про потік, зокрема:
блок потоку ядра;
ідентифікатор процесу, до якого належить потік, і покажчик на керуючий блок цього процесу (EPROCESS);
стартову адресу потоку, з якої почнеться виконання його коду;
інформацію для підсистеми безпеки.
Блок потоку ядра, у свою чергу, містить інформацію, необхідну ядру для організації планування і синхронізації потоків, зокрема:
покажчик на стек ядра;
інформацію для планувальника;
інформацію, необхідну для синхронізації цього потоку;
покажчик на блок оточення потоку.
Блок оточення потоку містить інформацію про потік, доступну для застосувань режиму користувача. До неї належать:
ідентифікатор потоку;
покажчик на стек режиму користувача;
покажчик на блок оточення процесу, до якого належить потік;
покажчик на локальну пам’ять потоку.
Створення потоків
Основним засобом створення потоків у WindowsХР є функція CreateThread() Win32 АРІ. Назвемо етапи виконання цієї функції.
В адресному просторі процесу створюють стек режиму користувача для потоку.
Ініціалізують апаратний контекст потоку (у процесор завантажують дані, що визначають його стан). Цей крок залежить від архітектури процесора.
Створюють об’єкт-потік виконавчої системи у призупиненому стані, для чого в режимі ядра:
створюють та ініціалізують структури даних потоку (блоки ETHREAD, KTHREAD, ТЕВ);
б) задають стартову адресу потоку (використовуючи передану як параметр адресу процедури потоку);
в) задають інформацію для підсистеми безпеки та ідентифікатор потоку;
виділяють місце під стек потоку ядра.
Підсистемі Win32 повідомляють про створення нового потоку.
Дескриптор та ідентифікатор потоку повертають у процес, що ініціював створення потоку (викликав CreateThread()).
Починають виконання потоку (виконують перехід за стартовою адресою).
Особливості програмного інтерфейсу потоків
Програмний інтерфейс керування потоками у WindowsХР є частиною Win32 АРІ. Такий інтерфейс ще називають інтерфейсом потоків Win32.
Створення потоків у Win32 АРІ
У Win32 АРІ, як зазначалося раніше, для створення потоку призначена функція CreateThreadO, а для його завершення - EndThreadO.
На практиці, однак, пару CreateThread( )/EndThread() є сенс використати лише тоді, коли з коду, що виконує потік, не викликаються функції стандартної бібліотеки мови С (такі, як printfOабо strcmpO).
Річ у тому, що функції стандартної бібліотеки С у Win32 АРІ не пристосовані до використання за умов багатопотоковості, і для того щоб підготувати потік до роботи за таких умов, необхідно під час його створення і завершення виконувати деякі додаткові дії. Ці дії враховані у спеціальних бібліотечних функціях роботи з потоками, описаних у заголовному файлі process. h. Це функція _beginthreadex() для створення потоку й _endthreadex() — для завершення потоку.
Розглянемо синтаксис функції beginthreadex(). Відразу ж наголосимо, що той самий набір параметрів (відмінний лише за типами) передають і у функцію CreateThread().
#inc1ude <process.h>
unsigned long _beginthreadex( void *security. unsigned stack_size, unsigned WINAPI (*thread_fun)(void *). void *argument, unsigned init_state. unsigned *tid );
де: security — атрибути безпеки цього потоку (NULL— атрибути безпеки за замовчуванням);
stack_size- розмір стека для потоку;
thread_fun- покажчик на функцію потоку;
argument— додаткові дані для передачі у функцію потоку;
іnit_state— початковий стан потоку під час створення (0 для потоку, що почне виконуватися негайно, CREATE_SUSPEND для припиненого);
tid— покажчик на змінну, в яку буде записано ідентифікатор потоку після виклику (0, якщо цей ідентифікатор не потрібний).
Функція _beginthreadex() повертає дескриптор створеного потоку, який потрібно перетворити в тип HANDLE:
HANDLE th= (HANDLE)_beginthreadex( ... );
Після отримання дескриптора, якщо він у цій функції більше не потрібний, його закривають за допомогою CloseHandlе() аналогічно до дескриптора процесу:
Завершення потоків у Win32 API
Функцію потоку можна завершити двома способами.
Виконати у ній звичайний оператор return(цей спосіб є найнадійнішим):
unsigned WINAPI thread_fun (void *num) { return 0:
}
Викликати функцію _endthreadex() з параметром, що дорівнює коду повернення:
unsigned WINAPI thread_fun (void *num) {
_endthreadex(0);
}
Контрольні питання:
Які складові елементи потоку?
Яка структура даних потоку?
Які основні етапи створення потоків?
Як здійснюється створення потоків у Win32 АРІ?
Як здійснюється завершення потоків у Win32 API?
Література: Шеховцов В.А. Операційні системи. – К.: Видавнича група BHV, 2005. – 576 с.: іл., стор. 82-87.