Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС_Шеховцов_1.docx
Скачиваний:
73
Добавлен:
09.11.2019
Размер:
14.73 Mб
Скачать

3.6.2.Ієрархія процесів

Після того як процес-предок створив процес-нащадок, потрібно забезпечити їх­ній взаємозв'язок. Є різні варіанти розв'язання цього завдання.

Можна організувати на рівні ОС однозначний зв'язок «предок-нащадок» так, щоб для кожного процесу завжди можна було визначити його предка. Наприклад, якщо процеси визначені унікальними ідентифікаторами, то для реалізації цього підходу в керуючому блоці процесу-нащадка повинен завжди зберігатися іденти­фікатор процесу-предка або посилання на його керуючий блок.

Таким чином формується ієрархія (дерево) процесів, оскільки нащадки мо­жуть у свою чергу створювати нових нащадків і т. ін. У таких системах звичайно існує

спеціальний вихідний процес (в UNIX-системах його називають і nit), з яко­го починається побудова дерева процесів (його запускає ядро системи). Якщо предок завершить виконання процесу перед своїм нащадком, функції предка бере на себе вихідний процес.

З іншого боку, зв'язок «предок-нащадок» можна не реалізовувати на рівні ОС. При цьому всі процеси виявляються рівноправними. Якщо зв'язок «предок-на­щадок» для конкретної пари процесів все ж таки потрібен, за його підтримку від­повідають самі процеси (процес-предок, наприклад, може сам зберегти свій іден­тифікатор у структурі даних нащадка у разі його створення).

Взаємозв'язок між процесами не обмежується лише відношеннями «предок-нащадок». Наприклад, у деяких ОС є поняття сесії (session). Така сесія поєднує всі процеси, створені користувачем за час інтерактивного сеансу його роботи із системою.

3.6.3.Керування адресним простором під час створення процесів

Оскільки основним елементом процесу є захищений адресний простір, дуже важ­ливо вирішити проблему його розподілу під час створення нового процесу. Роз­глянемо два різні підходи.

Системні виклики fork() і ехес()

У першому підході адресний простір нащадка створюють як точну копію адресного простору предка. Така операція реалізована системним викликом, який у POSIX-системах називають fork().

У цьому разі копіюється не тільки адресний простір, а й лічильник команд го­ловного потоку процесу, тому після виклику fork() предок і нащадок викону­ватимуть ту саму інструкцію. Розробник має визначити, у якому з двох процесів перебуває керування. Це можна зробити на підставі відмінностей між кодами по­вернення fork () для предка і нащадка.

Коли створення нового процесу відбувається шляхом дублювання адресного простору предка, виникає потреба у спеціальних засобах для завантаження про­грамного коду в адресний простір процесу. Такі засоби реалізує системний ви­клик, який у POSIX-системах називають ехес(). Як параметр для виклику ехес() треба вказувати весь шлях до виконуваного файла програми, який буде заванта­жено у пам'ять.

У системах із підтримкою fork() для того щоб запускати на виконання про­грами, після виклику fork () потрібно негайно викликати exec () (це називають технологією fork+exec).

Запуск застосування одним системним викликом

Другий підхід не розділяє дублювання адресного простору і завантаження коду — ці етапи тут поєднані в один. У даному разі системний виклик запускає на вико­нання задане застосування (зазвичай для цього йому потрібно вказати весь шлях до виконуваного файла цього застосування).

Можна виділити два етапи виконання такого системного виклику:

  • виділення пам'яті під адресний простір нового процесу (жодна інформація при цьому з адресного простору предка не копіюється);

  • завантаження виконуваного коду із зазначеного файла у виділений адресний простір.

Підхід із використанням fork() і ехес() є гнучкішим, бо він дає змогу в разі не­обхідності обмежитись якимось одним етапом запуску застосування. Сучасні ОС переважно реалізують деяку комбінацію першого та другого підходів.

Технологія копіювання під час запису

Якщо під час створення процесу за допомогою виклику fork () щоразу завчасно виділяти пам'ять і копіювати в неї дані адресного простору предка (стек, область глобальних змінних, програмний код), то це буде доволі трудомістким завдан­ням, особливо для процесів, що займають багато місця в пам'яті.

Для розв'язання цієї проблеми в сучасних ОС використовують технологію ко­піювання під час запису (copy-on-write). При цьому під час виклику fork () дані з пам'яті предка у пам'ять нащадка не копіюють, натомість відповідні ділянки пам'яті відображають в адресний простір — як нащадка, так і предка, але при цьо-му позначають їх як захищені від запису.

Як тільки нащадок або предок спробує змінити якусь із названих вище діля­нок пам'яті, тобто щось записати у неї, виникає апаратне переривання. Система реагує на нього, виділяє пам'ять під нову область, відкриту для запису відповід­ному процесу, і змінює адресний простір для обох процесів (наприклад, для дру­гого процесу відповідна ділянка пам'яті відкривається для запису). Слід зазначи­ти, що в разі використання цієї технології ділянки пам'яті, які не змінюються (наприклад, ті, що містять код програми), можуть взагалі ніколи не копіюватися.

У багатьох сучасних системах копіювання під час запису є основною техноло­гією керування адресним простором у разі створення процесів.