- •9.3. Створення процесів
- •Базові поняття процесів і потоків
- •1.1. Процеси і потоки в сучасних ос
- •1.2. Моделі процесів і потоків
- •1.3. Складові елементи процесів і потоків
- •2. Багатопотоковість та її реалізація
- •2.1. Поняття паралелізму
- •2.2. Види паралелізму
- •2.4. Способи реалізації моделі потоків
- •2.3. Переваги і недоліки багато потоковості
- •3. Стани процесів і потоків
- •4. Опис процесів і потоків
- •4.1. Керуючі блоки процесів і потоків
- •4.2. Образи процесу і потоку
- •5. Перемикання контексту й обробка переривань
- •5.1. Організація перемикання контексту
- •5.2. Обробка переривань
- •6. Створення і завершення процесів і потоків
- •6.1. Створення процесів
- •6.2. Ієрархія процесів
- •6.3. Керування адресним простором під час створення процесів
- •6.4. Особливості завершення процесів
- •6.5. Синхронне й асинхронне виконання процесів
- •6.6. Створення і завершення потоків
- •7. Керування процесами в unix і Linux
- •7.1. Образ процесу
- •7.2. Ідентифікаційна інформація та атрибути безпеки процесу
- •7.3. Керуючий блок процесу
- •7.5. Завершення процесу
- •7.7. Запуск програми
- •7.8. Очікування завершення процесу
- •7.9. Сигнали
- •8. Керування потоками в Linux
- •8.1. Базова підтримка багато потоковості
- •8.2. Особливості нової реалізації багато потоковості в ядрі Linux
- •8.3. Потоки ядра Linux
- •8.4. Програмний інтерфейс керування потоками posix
- •9. Керування процесами у Windows хр
- •9.1. Складові елементи процесу
- •9.2. Структури даних процесу
- •9.3. Створення процесів
- •9.4. Завершення процесів
- •9.5. Процеси і ресурси. Таблиця об’єктів процесу
- •9.6. Програмний інтерфейс керування процесами Win32 арі
- •10. Керування потоками у Windows хр
- •10.1. Складові елементи потоку
- •10.2. Структури даних потоку
- •10.3. Створення потоків
- •10.4. Особливості програмного інтерфейсу потоків
- •Висновки
- •Контрольні запитання та завдання
9.6. Програмний інтерфейс керування процесами Win32 арі
Зараз ми вперше торкнемося практичних особливостей програмування у Win32 АРІ. Перш ніж перейти до основного матеріалу, зробимо кілька зауважень.
Насамперед слід звернути увагу на систему типів Win32 АРІ. Розробники цього АРІ для визначення типів широко застосовували синоніми імен тинів, тому потрібно вміти знаходити в типах Win32 АРІ традиційні типи мови С. Виділимо деякі базові типи:
♦ B00L — його використовують для зберігання логічного значення, насправді він є цілочисловим;
♦ DWORD — двобайтовий цілочисловий тип без знака, аналог unsigned int;
♦ HANDLE— цілочисловий дескриптор об’єкта;
♦ LPTSTR — покажчик на рядок, що складається із двобайтових або однобайтових символів (залежно від режиму компіляції програми — із підтримкою Unicode або без неї), аналог char * або wchar_t *;
♦ LPCTSTR — покажчик на константний рядок, аналог const char * або const wchar_t *
Взагалі для створення імені типу покажчика потрібно додати до імені базового типу префікс LP. Таке утворення імен траплятиметься й далі (наприклад, LPV0ID означає void *, LPSECURITY_ATTRIBUTES — покажчик на структуру SECURITY_ATTRIBUTES).
Для використання засобів Win32 АРІ у більшості випадків достатньо підключити заголовний файл windows.h. Надалі підключення цього файла матиметься на увазі за замовчуванням.
Для закриття дескрипторів об’єктів буде використана АРІ-функція
CloseHandle( ).
Створення процесів у Win32 АРІ
Як ми вже зазначали, для створення нового процесу у Win32 використовують функцію CreateProcess( ).
де: app_name — весь шлях до виконуваного файла (NULL - ім’я виконуваного файла можна отримати з другого аргументу):
cmd_linе — повний командний рядок для запуску виконуваного файла, можливо, із параметрами (цей рядок виконується, якщо app_name дорівнює NULL, зазвичай так запускати процес зручніше):
psa_proc, psa_thr — атрибути безпеки для всього процесу і для головного потоку (особливості їхнього задання розглянемо пізніше, а доти як значення всіх параметрів типу LPSECURITY_ATTRIBUTES задаватимемо NULL, що означає задання атрибутів безпеки за замовчуванням);
inherit_handles — керує спадкуванням нащадками дескрипторів об’єктів, які використовуються у процесі (питання спадкування дескрипторів будуть розглянуті пізніше);
f1ag_create - маска прапорців, які керують створенням нового процесу (наприклад, прапорець CREATE_NEW_CONSOLE означає, що процес запускається в новому консольному вікні);
environ — покажчик на пам’ять із новими змінними оточення, які предок може задавати для нащадка (NULL — нащадок успадковує змінні оточення предка);
cur_dir - рядок із новим значенням поточного каталогу для нащадка (NULL - нащадок успадковує поточний каталог предка);
startup_info — покажчик на заздалегідь визначену структуру даних типу STARTUP INFO, на базі якої задають параметри для процесу-нащадка;
process_info — покажчик на заздалегідь визначену структуру даних PROCFSS_ INFORMATION, яку заповнює ОС під час виклику CreatePrccess( ).
Серед полів структури STARTUPINFO можна виділити:
♦ cb — розмір структури у байтах (це її перше за порядком поле). Звичайно перед заповненням всю структуру обнуляють, задаючи тільки cb:
♦ lpTitle — рядок заголовка вікна для нової консолі:
Структура PROCESS__INFORMATION містить чотири поля:
♦ hProcess — дескриптор створеного процесу;
♦ hThread — дескриптор його головного потоку;
♦ dwProcessId — ідентифікатор процесу (process id, pid);
♦ dwThreadld — ідентифікатор головного потоку (thread id, tid).
Ідентифікатор pid унікально визначає процес на рівні ОС. ОС повторно використовує pid уже завершених процесів, тому небажано запам’ятовувати їхнє значення, якщо процес уже завершився або закінчився помилкою.
CreateProcess( ) повертає нуль, якщо під час запуску процесу сталася помилка.
Наведемо приклад виклику CreateProcess( ), у якому вказані значення всіх необхідних параметрів:
Після створення процесу може виникнути необхідність змінити його характеристики з коду, який він виконує. Для цього треба отримати доступ до дескриптора поточного процесу за допомогою функції GetCurrentProcess( ):
Ідентифікатор поточного процесу можна отримати за допомогою функції Get- CurrentProcessId( ):
Завершення процесів у Win32 API
Для завершення процесів використовують функцію ExitProcess( ):
де exitcode - код повернення процесу. Наприклад
Для завершення іншого процесу використовують функцію ТеrminateProcess( ):
У процесі, який запустив інший процес, можна отримати код завершення цього процесу за допомогою функції
Тут pexit_code — покажчик на змінну, в яку заносять код завершення.
Синхронне й асинхронне виконання процесів у Win32 АРІ
Для того щоб реалізувати синхронне виконання, після успішного виконання CreateProcess( ) процес-предок має викликати функцію очікування закінчення нащадка. Це WaitForSingleObject( ), стандартна функція очікування зміни стану об’єкта Win32 АРІ.
Тут ph — дескриптор нащадка; timeout -- максимальний час очікування в мілісекундах (INFINITE - необмежено).
Повернене значення може бути WAIT_FAILED через помилку.
Для асинхронного виконання достатньо відразу ж закрити обидва дескриптори і не викликати WaitForSingleObject( ):
