- •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. Особливості програмного інтерфейсу потоків
- •Висновки
- •Контрольні запитання та завдання
7. Керування процесами в unix і Linux
7.1. Образ процесу
В UNIX-системах образ процесу містить такі компоненти:
♦ керуючий блок процесу;
♦ код програми, яку виконує процес;
♦ стек процесу, де зберігаються тимчасові дані (параметри процедур, повернені значення, локальні змінні тощо);
♦ глобальні дані, спільні для всього процесу.
Для кожного компонента образу процесу виділяють окрему ділянку пам’яті. У подальшому буде докладно розглянуто структуру різних ділянок пам’яті процесу та особливості їхнього використання.
7.2. Ідентифікаційна інформація та атрибути безпеки процесу
Із кожним процесом у системі пов’язана ідентифікаційна інформація.
Ідентифікатор процесу (pid) є унікальним у межах усієї системи, і його використовують для доступу до цього процесу. Ідентифікатор процесу і nit завжди дорівнює одиниці.
Ідентифікатор процесу-предка (ppid) задають під час його створення. Будь - який процес має мати доступ до цього ідентифікатора. Так в UNIX-системах обов’язково підтримується зв’язок «предок-нащадок». Якщо предок процесу Р завершує виконання, предком цього процесу автоматично стає іnit, тому ppid для Р дорівнюватиме одиниці.
Із процесом також пов’язаний набір атрибутів безпеки.
♦ Реальні ідентифікатори користувача і групи процесу (uid, gid) відповідають користувачеві, що запустив програму, внаслідок чого в системі з’явився відповідний процес.
♦ Ефективні ідентифікатори користувача і групи процесу (euid, egid) використовують у спеціальному режимі виконання процесу -- виконанні з правами власника. Цей режим буде розглянуто у подальшому.
7.3. Керуючий блок процесу
Розглянемо структуру керуючого блоку процесу в Linux і відмінності його реалізації у традиційних UNIX-системах.
Керуючий блок процесу в Linux відображається структурою даних task_struct. До найважливіших полів цієї структури належать поля, що містять таку інформацію:
♦ ідентифікаційні дані (зокрема pid — ідентифікатор процесу);
♦ стан процесу (виконання, очікування тощо);
♦ покажчики на структури предка і нащадків;
час створення процесу та загальний час виконання (так звані таймери процесу);
♦ стан процесора (вміст регістрів і лічильник інструкцій);
♦ атрибути безпеки процесу (uid, gid, euid, egid).
Зазначимо, що в ядрі Linux відсутня окрема структура даних для потоку, тому інформація про стан процесора міститься в керуючому блоці процесу.
Крім перелічених вище, task_struct мас кілька полів спеціалізованого призначення, необхідних для різних підсистем Linux:
♦ відомості для обробки сигналів;
♦ інформація для планування процесів;
інформація про файли і каталоги, пов’язані із процесом;
♦ структури даних для підсистеми керування пам'яттю.
Дані полів task_struct можуть спільно використовувати декілька процесів спеціалізованого призначення, у цьому випадку такі процеси фактично є потоками. Докладніше дане питання буде розглянуте під час вивчення реалізації багатопотоковості в Linux.
Керуючі блоки процесу зберігаються в ядрі у спеціальній структурі даних. До появи ядра версії 2.4 таку структуру називали таблицею процесів системи; це був масив, максимальна довжина якого не могла перевищувати 4 Кбайт. У ядрі версії 2.4 таблиця процесів була замінена двома динамічними структурами даних, що не мають такого обмеження на довжину:
♦ хеш-таблицею (де в ролі хеша виступає pid процесу), ця структура дає змогу швидко знаходити процес за його ідентифікатором;
♦ кільцевим двозв’язним списком, ця структура забезпечує виконання дій у цик¬лі для всіх процесів системи.
Тепер обмеження на максимальну кількість процесів перевіряється тільки всередині реалізації функції fork ( ) і залежить від обсягу доступної пам’яті (наприклад, є відомості, що у системі з 512 Мбайт пам’яті можна створити близько 32 000 процесів).
Для нащадка fork( ) повертає нуль, а для предка — ідентифікатор (pid) створеного процесу-нащадка. Коли з якоїсь причини нащадок не був створений, fork( ) поверне -1. Тому звичайний код роботи з fork ( ) має такий вигляд:
Після створення процесу він може дістати доступ до ідентифікаційної інформації за допомогою системного виклику getpid( ), який повертає ідентифікатор поточного процесу, і getppid( ), що повертає ідентифікатор процесу-предка:
