Читайте также:
|
|
У разі завершення процесу відповідний об'єкт-процес стає кандидатом на вилучення із системи. При цьому диспетчер об’єктів викликає метод delete для об’єктів-процесів, який закриває всі дескриптори в таблиці об'єктів цього процесу.
Процеси і ресурси. Таблиця об’єктів процесу
Кожен процес, як було показано в розділі 2, може користуватися ресурсами через
дескриптори відповідних об'єктів. Відкриті дескриптори об’єктів є індексами
в таблиці об'єктів (object table), що зберігається в керуючому блоці процесу. Ця
таблиця містить покажчики на всі об'єкти, дескриптори яких відкриті процесом.
Процес може отримати дескриптор об'єкта кількома способами:
♦ створивши новий об'єкт;
♦ відкривши дескриптор наявного об'єкта;
♦ успадкувавши дескриптор від іншого процесу;
♦ отримавши дублікат дескриптора з іншого процесу.
Кожен елемент таблиці об'єктів містить права доступу відповідного дескрип-
тора і його режим спадкування, який визначає, чи отримають процеси, створені розглядуваним процесом, копію дескриптора відповідного об'єкта. Режим спадкування задають під час створення об'єкта.
Об'єкт може одночасно бути використаний декількома процесами, при цьому
кожен з них отримує унікальний дескриптор, що відповідає цьому об'єкту.
3.9.6. Програмний інтерфейс керування процесами
Win32 АРІ
У цьому розділі ми вперше торкнемося практичних особливостей програмування
у Win32 АРІ [31, 50]. Перш ніж перейти до основного матеріалу, зробимо кілька
зауважень.
Насамперед слід звернути увагу на систему типів Win32 АРІ. Розробники
цього АРІ для визначення типів широко застосовували синоніми імен типів, тому
потрібно вміти знаходити в типах Win32 АРІ традиційні типи мови С. Виділимо
деякі базові типи:
♦ B00L - його використовують для зберігання логічного значення, насправді він
є цілочисловим;
♦ DWORD — двобайтовий цілочисловий тип без знака, аналог unsigned int;
♦ HANDLE — цілочисловий дескриптор об'єкта;
♦ LPTSTR — покажчик на рядок, що складається із двобайтових або однобайтових
символів (залежно від режиму компіляції програми — із підтримкою Unicode
або без неї), аналог char * або wcharj: *;
♦ LPCTSTR — покажчик на константний рядок, аналог const char * або const
wchar_t *
Взагалі для створення імені типу покажчика потрібно додати до імені базового
типу префікс LP. Таке утворення імен траплятиметься й далі (наприклад, LPV0ID означає void *, LPSECURITY__ATTRIBUTES — покажчик на структуру SECURITY_ATTRIBUTES).
Для використання засобів Win32 АРІ у більшості випадків достатньо підключити заголовний файл windows.h. Надалі підключення цього файла матиметься на
увазі за замовчуванням.
Для закриття дескрипторів об'єктів буде використана API-функція CloseHandlе ().
Створення процесів у Win32 АРІ
Як ми вже зазначали, для створення нового процесу у Win32 використовують
функцію CreateProcess().
BOOL CreateProcess (LPCTSTR app_name. LPCTSTR cmd_line,
LPSECURITY_ATTRIBUTES psa_proc, LPSECURITY_ATTRIBUTES psa_thr,
BOOL іnherit_handles. DWORD flag_create,
LPVOID environ. LPTSTR cur_dir.
LPSTARTUPINFO startup_info. LPPR0CESS_INF0RMATI0N process_info);
де: app_name — весь шлях до виконуваного файла (NULL - ім’я виконуваного файла
можна отримати з другого аргументу):
CreateProcess("C:/winnt/notepad.exe"....);
cmd_line - повний командний рядок для запуску виконуваного файла, можливо, із параметрами (цей рядок виконується, якщо арр_name дорівнює NULL, зазвичай так запускати процес зручніше):
CreateProcess(NULL. "С:/winnt/notepad test.txt"....):
psa_proc, psa_thr - атрибути безпеки для всього процесу і для головного потоку (особливості їхнього задання розглянемо в розділах 11 і 18, а доти як значення всіх параметрів типу LPSECURITY_ATTRIBUTES задаватимемо NULL, що означає задання атрибутів безпеки за замовчуванням);
inherit_handles - керує спадкуванням нащадками дескрипторів об'єктів, які
використовуються у процесі (питання спадкування дескрипторів будуть розглянуті в розділах 11 і 13);
flag_create — маска прапорців, які керують створенням нового процесу (наприклад, прапорець CREATE_NEW_CONSOLE означає, що процес запускається в новому консольному вікні);
environ — покажчик на пам'ять із новими змінними оточення, які предок може
задавати для нащадка (NULL — нащадок успадковує змінні оточення предка);
cur_dir — рядок із новим значенням поточного каталогу для нащадка (NULL -
нащадок успадковує поточний каталог предка);
startup_info - покажчик на заздалегідь визначену структуру даних типу
STARTUP INFO, на базі якої задають параметри для процесу-нащадка;
process_infо — покажчик на заздалегідь визначену структуру даних PROCESS_INFORMATION, яку заповнює ОС під час виклику CreateProcess().
Серед полів структури STARTUPINFO можна виділити:
♦ cb — розмір структури у байтах (це її перше за порядком поле). Звичайно перед заповненням всю структуру обнуляють, задаючи тільки cb:
STARTUPINFO si = { sizeof(si) };
♦ IpTitle — рядок заголовка вікна для нової консолі:
//... si обнуляється
si.IpTitle = "Мій процес-нащадок";
Структура PR0CESS_INF0RMATI0N містить чотири поля:
♦ hProcess — дескриптор створеного процесу;
♦ hThread — дескриптор його головного потоку;
♦ dwProcessId — ідентифікатор процесу (process id, pid);
♦ dwThreadld — ідентифікатор головного потоку (thread id, tid).
Ідентифікатор pid унікально визначає процес на рівні ОС. ОС повторно використовує pid уже завершених процесів, тому небажано запам'ятовувати їхнє значення, якщо процес уже завершився або закінчився помилкою.
CreateProcess() повертає нуль, якщо під час запуску процесу сталася помилка.
Наведемо приклад виклику CreateProcess (), у якому вказані значення всіх необхідних параметрів:
//... задається si
PROCESS_INFORMATION pi:
CreateProcess (NULL, " C:/winnt/notepad test.txt", NULL, NULL, TRUE,
CREATE_NEW_C0NS0LE, NULL, "D:/", &si, &pi);
printf (“pid=%d, tid=*d\n", pi.dwProcessId, pi.dwThreadld):
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
Після створення процесу може виникнути необхідність змінити його характеристики з коду, який він виконує. Для цього треба отримати доступ до дескриптора поточного процесу за допомогою функції GetCurrentProcess ():
HANDLE curph = GetCurrentProcess ():
Ідентифікатор поточного процесу можна отримати за допомогою функції Get-
CurrentProcessId():
int pid = GetCurrentProcessId ();
Завершення процесів у Win32 API
Для завершення процесів використовують функцію ExitProcess ():
VOID ExitProcess (UINT exitcode):
де exitcode - код повернення процесу. Наприклад
ExitProcess (100); // вихід з кодом 100
Для завершення іншого процесу використовують функцію TerminateProcess ():
BOOL TerminateProcess (HANDLE hProcess, UINT exitcode):
У процесі, який запустив інший процес, можна отримати код завершення цього
процесу за допомогою функції
GetExitCodeProcess (HANDLE hProcess, LPDW0RD pexit_code):
Тут pexit_code — покажчик на змінну, в яку заносять код завершення.
int exitcode:
GetExitCodeProcess(pi.hProcess, &exitcode):
printf ("Код повернення =%d\n", exitcode);
Синхронне й асинхронне виконання процесів у Win32 АРІ
Для того щоб реалізувати синхронне виконання, після успішного виконання
CreateProcess() процес-предок має викликати функцію очікування закінчення нащадка. Це WaitForSingleObject (), стандартна функція очікування зміни стану об'єкта
Win32 АРІ.
DWORD WaitForSingleObject (HANDLE ph. DWORD timeout);
Тут ph - дескриптор нащадка; timeout — максимальний час очікування в мілісекундах (INFINITE - необмежено).
Повернене значення може бути WAIT_FAILED через помилку.
BOOL res;
if (res = CreateProcess(..., &pi)) {
CloseHandle(pi.hThread);
if (WaitForSingleObject(pi.hProcess. INFINITE)!= WAITFAILED)
GetExitCodeProcess(pi.hProcess, &exitcode);
}
CloseHandle(pi.hProcess);
}
Для асинхронного виконання достатньо відразу ж закрити обидва дескриптори і не викликати WaitForSingleObject ():
if (res = CreateProcess(.... &pi)) {
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
3.10. Керування потоками у Windows ХР
Для того щоб виконувати код, у рамках процесу обов’язково необхідно створити
потік. У системі Windows ХР реалізована модель потоків «у чистому вигляді».
Процеси і потоки є різними сутностями в системі, що перебувають у чітко визначеному взаємозв'язку один з одним; для роботи з ними використовують різні
системні виклики. У Windows ХР ніколи не використовували модель процесів,
подібну до традиційної моделі UNIX.
Багатопотоковість Windows ХР базується на схемі 1:1. Кожному потоку користувача відповідає сутність у ядрі, при цьому ядро відповідає за планування потоків. Процеси не плануються.
Дата добавления: 2014-12-20; просмотров: 157 | Поможем написать вашу работу | Нарушение авторских прав |