Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_Р2.doc
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
1.63 Mб
Скачать

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); }