
- •Тема 2.1 Базові поняття процесів і потоків
- •2.1.1 Процеси і потоки в сучасних ос
- •Моделі процесів і потоків
- •2.1.3 Складові елементи процесів і потоків
- •Тема 2.2 Багатопотоковість та її реалізація
- •2.2.1 Поняття паралелізму
- •Види паралелізму
- •Переваги і недоліки багато потоковості
- •2.2.4 Способи реалізації моделі потоків
- •2.3 Тема Стани процесів
- •2.3.1 Стан процесу
- •2.3.2 Двох -станова модель процесу
- •2.3.3 Пяти-станова модель процесу
- •2.3.4 Процес та його життєвий цикл
- •2.4.1 Керуючі блоки процесів і потоків
- •2.4.2 Образи процесу і потоку.
- •2.5 Тема Перемикання контексту й обробка переривань
- •2.5.1Організація перемикання контексту
- •2.5.2 Обробка переривань
- •2.6 Тема Створення і завершення процесів і потоків
- •2.6.1 Створення процесів
- •2.6.2 Ієрархія процесів
- •2.6.3 Керування адресним простором під час створення процесів
- •2.6.4 Особливості завершення процесів
- •2.6.5 Створення і завершення потоків
- •2.7 Тема Мультипроцесування
- •2.7.1 Підходи реалізації мультипроцесування.
- •7.2.2 Види комп’ютерних систем з використанням декількох центральних процесорів
- •2.8 Тема Види міжпроцесової взаємодії
- •2.8.1.Проблеми міжпроцесової взаємодії
- •2.8.2 Види міжпроцесової взаємодії.
- •2.8.3 Особливості міжпроцесової взаємодії.
- •2.9 Тема Базові механізми міжпроцесової взаємодії
- •2.9.1 Міжпроцесова взаємодія на базі спільної пам'яті.
- •2.9.2 Основи передавання повідомлень.
- •2.10 Тема Керування процесами у Windows xp
- •2.10.1 Складові елементи процесу
- •2.10.2 Структури даних процесу
- •2.10.3 Створення процесів
- •2.10.4.Завершення процесів
- •2.10.5 Програмний інтерфейс керування процесами Win32 арі
- •2.11 Тема Керування потоками у Windows xp
- •2.11.1 Складові елементи потоку
- •2.11.2 Структури даних потоку
- •2.11.3 Створення потоків
- •2.11.4 Особливості програмного інтерфейсу потоків
- •2.11.5 Завершення потоків у Win32 api
- •2.12 Тема Керування процесами та потоками в unix і Linux
- •2.12.1 Керування процесами в unix і Linux
- •Керування потоками в Linux
2.10.5 Програмний інтерфейс керування процесами Win32 арі
Слід звернути увагу на систему типів Win32 АРІ. Розробники цього АРІ для визначення типів широко застосовували синоніми імен типів, тому потрібно вміти знаходити в типах Win32 АРІ традиційні типи мови С. Виділимо деякі базові типи:
BOOL — його використовують для зберігання логічного значення, насправді він є цілочисловим;
DWORD — двобайтовий цілочисловий тип без знака, аналог unsigned int; 4- HANDLE — цілочисловий дескриптор об'єкта;
LPTSTR — покажчик на рядок, що складається із двобайтових або однобайтових символів (залежно від режиму компіляції програми — із підтримкою Unicode або без неї), аналог char * або wchar_t *;
LPCTSTR — покажчик на константний рядок, аналог const char * або const wchar_t *
Взагалі для створення імені типу покажчика потрібно додати до імені базового типу префікс LP. Таке утворення імен траплятиметься й далі (наприклад, LPVOID означає void * LPSECURITY_ATTRIBUTES - покажчик на структуру SECURITY_ATTRIBUTES).
Для використання засобів Win32 АРІ у більшості випадків достатньо підключити заголовний файл windows .h. Надалі підключення цього файла матиметься на увазі за замовчуванням.
Для закриття дескрипторів об'єктів буде використана API-функція CloseHandle().
Створення процесів у Win32 АРІ
Як ми вже зазначали, для створення нового процесу у Win32 використовують функцію CreateProcessO.
BOOL CreateProcess ( LPCTSTR appjiame. LPCTSTR cmdjine.
LPSECURITY_ATTRIBUTES psa_proc. LPSECURITY_ATTRIBUTES psa_thr.
BOOL inheritjiandles, DWORD flag_create,
LPVOID environ. LPTSTR cur_dir.
LPSTARTUPINFO startupjnfo. LPPROCESSJNFORMATION process jnf о );
де: appjiame — весь шлях до виконуваного файла (NULL — ім'я виконуваного файла можна отримати з другого аргументу):
CreateProcess("С:/winnt/notepad.exe". ...);
cmd_line — повний командний рядок для запуску виконуваного файла, можливо, із параметрами (цей рядок виконується, якщо appname дорівнює NULL, зазвичай так запускати процес зручніше):
CreateProcessCNULL, "C:/winnt/notepad test.txt". ...);
psa_proc, psa_thr — атрибути безпеки для всього процесу і для головного потоку (значення всіх параметрів типу LPSECURITY_ATTRIBUTES задаємо NULL, що означає задання атрибутів безпеки за замовчуванням);
inheritjiandles — керує спадкуванням нащадками дескрипторів об'єктів, які використовуються у процесі ;
flag_create — маска прапорців, які керують створенням нового процесу (наприклад, прапорець CREATE_NEW_CONSOLE означає, що процес запускається в новому консольному вікні);
envi гоп — покажчик на пам'ять із новими змінними оточення, які предок може задавати для нащадка (NULL — нащадок успадковує змінні оточення предка);
cur_dir - рядок із новим значенням поточного каталогу для нащадка (NULL -нащадок успадковує поточний каталог предка);
startup_info — покажчик на заздалегідь визначену структуру даних типу STARTUP INFO, на базі якої задають параметри для процесу-нащадка;
process_info — покажчик на заздалегідь визначену структуру даних PROCESS_ INFORMATION, яку заповнює ОС під час виклику CreateProcess().
Серед полів структури STARTUP INFO можна виділити:
cb — розмір структури у байтах (це її перше за порядком поле). Звичайно перед заповненням всю структуру обнуляють, задаючи тільки cb:
STARTUPINFO si = { sizeof(si) }:
ipTitle — рядок заголовка вікна для нової консолі:
// ... si обнуляється
si.IpTitle "Мій процес-нащадок";
Структура PROCESS_INFORMATION містить чотири поля:
hProcess — дескриптор створеного процесу;
hThread — дескриптор його головного потоку;
dwProcessId — ідентифікатор процесу (process id, pid);
dwThreadld — ідентифікатор головного потоку (thread id, tid).
Ідентифікатор pid унікально визначає процес на рівні ОС. ОС повторно використовує pid уже завершених процесів, тому небажано запам'ятовувати їхнє значення, якщо процес уже завершився або закінчився помилкою.
CreateProcessO повертає нуль, якщо під час запуску процесу сталася помилка.
Наведемо приклад виклику CreateProcess(), у якому вказані значення всіх необхідних параметрів:
// ... задається si
PROCESSJNFORMATION pi;
CreateProcess (NULL. " C:/winnt/notepad test.txt", NULL. NULL. TRUE.
CREATE_NEW_CONSOLE. NULL. "D:/11. &si. &pi); printf ("pid=$d. tid=Јd\n", pi.dwProcessId. pi.dwThreadld): CloseHandieCpi.hThread); CloseHandle(pi.hProcess);
Після створення процесу може виникнути необхідність змінити його характеристики з коду, який він виконує. Для цього треба отримати доступ до дескриптора поточного процесу за допомогою функції GetCurrentProcess():
HANDLE curph – GetCurrentProcess();
Ідентифікатор поточного процесу можна отримати за допомогою функції GetijrrentProcessId():
int pid = GetCurrentProcessId();
Завершення процесів у Win32 API
Для завершення процесів використовують функцію Exit Process():
VOID ExitProcess (UINT exitcode); де exitcode — код повернення процесу. Наприклад
ExitProcess (100); // вихід з кодом 100
Для завершення іншого процесу використовують функцію Termi nateProcess(): BOOL TerminateProcess (HANDLE hProcess. UINT exitcode);
У процесі, який запустив інший процес, можна отримати код завершення цього процесу за допомогою функції
GetExitCodeProcess (HANDLE hProcess. LPDWORD pexit_code);
Тут pexitcode — покажчик на змінну, в яку заносять код завершення.
int exitcode;
GetExitCodeProcess(pi.hProcess, Sexitcode);
printf ("Код повернення =&d\n", exitcode);
Синхронне й асинхронне виконання процесів у Win32 АРІ
Для того щоб реалізувати синхронне виконання, після успішного виконання CreateProcess() процес-предок має викликати функцію очікування закінчення нащадка. Це Wai tForSi ngl eObject(), стандартна функція очікування зміни стану об'єкта Win32 АРІ.
DWORD WaitForSingleObject (HANDLE ph. DWORD timeout);
Тут ph — дескриптор нащадка; timeout — максимальний час очікування в мілісе-кундах (INFINITE — необмежено).
Повернене значення може бути WAITFAILED через помилку.
BOOL res;
if (res ■ CreateProcess(... , &pi)) {
CloseHandle(pi.hThread);
if (WaitForSingleObject(pi.hProcess. INFINITE) != WAITJAILED) GetExitCodeProcess(pi.hProcess. &exitcode);
}
CloseHandleCpi.hProcess):
}
Для асинхронного виконання достатньо відразу ж закрити обидва дескриптори і не викликати WaitForSingleObject():
if (res = CreateProcess(... . &pi)) {
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess); }