
- •Операційні системи
- •1.Принципи побудови ос. Теоретичні основи процесу
- •2. Властивості та класифікація процесів. Життєвий цикл процесу.
- •Арі процесів. Функція fork. Функція exit.
- •Сигнали. Функція wait, waitpid. Функція exec.
- •Ресурси ос. Визначення ресурсу. Властивості та класифікація ресурсів.
- •Концепція віртуалізації. Віртуальна машина.
- •Дисципліни розподілу ресурсів які використовуються в ос.
- •Концепція переривань Теорія переривань
- •Блокування. Сигнали. Сигнальна маска. Функція sigaction.
- •Процеси-демони. Поняття про демони. Основні демони unix. Приклад програми демону
- •Засоби, механізми і підсистеми ос. Системи керування процесами. Дворівнева система керування процесами.
- •Засоби, механізми і підсистеми ос. Рівень довгострокового планування. Схема довгострокового рівня планування.
- •Засоби, механізми і підсистеми ос. Рівень короткострокового планування. Схема рівня планування.
- •Структури даних процесів. Стан процесів у unix. Особливості планувальника unix ( Linux).
- •Дескриптори процесів.
- •Взаємодія між процесами у unix.
- •Канали. Fifo (First InFirst Out). Повідомлення (черги повідомлень).
- •Семафори. Задачі синхронізації.
- •Архітектура та основні питання побудови механізмів синхронізації
- •Семафорна техніка синхронізації та упорядкування процесів.
- •Підсистема введення/виведення системи unix. Драйвери пристроїв. Типи драйверів. Базова архітектура драйверів
- •Файлова підсистема ос. Суперблок. Індексні дескриптори. Імена файлів. Каталоги.
- •Побудова підсистем ядра мультипрограмних ос. Організація віртуальної оп. Основні поняття та принципи віртуалізації пам’яті.
- •Принципи керування пам’яттю у unix. Віртуальна та фізична пам’ять. Сегменти. Сторінковий механізм.
- •Адресний простір процесів. Керування пам’яттю процесу.
- •Планування виконання процесі. Обробка переривань таймеру. Відкладений виклик. Аларми. Контекст процесу.
- •Архітектура віртуальної фс. Віртуальні індексні дескриптори. Монтування фс.
- •Архітектура віртуальної фс. Трансляції імен. Доступ до фс. Файлова таблиця.
- •Архітектура віртуальної фс. Блокування доступу до файлу.
Арі процесів. Функція fork. Функція exit.
Функція fork Ще один спосіб створення нового процесу - клонування поточного Peri-процесу за допомогою UNIX-функції fork. Функція fork робить те ж саме, що і системний виклик fork (2): створює клон поточного процесу. Цей клон (він називається породженим процесом, а оригінал - батьківським) використовує той же виконуваний код, ті ж змінні і навіть ті ж відкриті файли. Розрізняються ці два процеси по поверненню значенню функції fork: для породженого процесу воно дорівнює нулю, а для батьківського - ненульове (або undef, якщо цей системний виклик виявиться невдалим). Ненульове значення, одержуване батьківським процесом, - це не що інше як ідентифікатор породженого процесу.Вы можете проверить возвращаемое значение и действовать соответственно: if ("defined($child_pid = fork()) { die "cannot fork: $""; } elsif ($pid) { # я - родительский процесс } else { # я - порожденный процесс } Чтобы максимально эффективно использовать этот клон, нам нужно изучить еще несколько функций, которые весьма похожи на своих UNIX-тезок: это функции wait, exit и ехес. Найпростіша з них - функція Ехес. Це майже те ж саме, що і функція system, за тим винятком, що замість запуску нового процесу для виконання shell-команди Perl замінює поточний процес на shell. Після успішного виконання Ехес Perl-програма зникає, оскільки замість неї виконується Незатребувана програма.
Наприклад, Ехес "date";
замінює поточну Perl-програму командою date, направляючи результат цієї команди на стандартний висновок Perl-програми. Після завершення команди date робити більше нічого, тому що Perl-програма давно зникла.
Все це можна розглядати і по-іншому: функція system схожа на комбінацію функції fork з функцією Ехес, наприклад: # МЕТОД 1... использование system: system("date"); # МЕТОД 2... использование fork/ехес: unless (fork) { # fork выдала нуль, поэтому я - порожденный процесс и я выполняю: exec("date"); # порожденный процесс становится командой date } Використовувати fork і Ехес таким способом - не зовсім правильно, тому що команда date і батьківський процес "пихтять" одночасно, їх резуль ¬ тати можуть перемішатися і зіпсувати всю справу. Як дати батьківському процесу вказівку почекати, поки не завершиться породжений процес? Саме це і робить функція wait ", вона чекає завершення даного (та й будь-якого, якщо бути точним) породженого процесу. Функція waitpid більш розбірлива: вона чекає завершення не будь-якого, а певного породженого процесу: if ("defined($kidpid = fork() { # fork возвратила undef, т.е. неудача die "cannot fork: $""; } elsif ($pid == 0) { # fork возвратила 0, поэтому данная ветвь - порожденный процесс ехес("date"); # если ехес терпит неудачу, перейти к следующему оператору die "can"t exec date: $""; } else { # fork возвратила не 0 и не undef, # поэтому данная ветвь - родительский процесс waitpid($kidpid, 0); } Якщо все це здається вам занадто складним, вивчіть системні виклики fork (2) і Ехес (2), відшукавши матеріали про них в якомусь керівництво по ОС UNIX, тому що Perl просто передає виклики цих функцій прямо в системні виклики UNIX
Функція exit забезпечує негайний вихід з поточного Perl-процесу. Вона використовується для переривання Perl-програми небудь посередині або - разом з функцією fork - для виконання Perl-коду в процесі з подальшим виходом. Ось приклад видалення декількох файлів з каталогу / tmp у фоновому режимі за допомогою породженого Perl-процесу: unless (defined ($pid = fork)) { die "cannot fork: $""; } unless ($pid) { unlink ; # удалить эти файлы exit; # порожденный процесс останавливается здесь ) # родительский процесс продолжается здесь waitpid ($ pid, 0); # після знищення породженого процесу потрібно все прибрати
Без використання функції exit породжений процес продовжував би виконувати Perl-код (з рядка "# батьківський процес триває тут") - а як раз цього нам і не потрібно.
Функція exit може мати необов'язковий параметр, службовець числовим кодом виходу, який сприймається батьківським процесом Типово вихід проводиться з нульовим кодом, що показує, що все пройшло нормально.
Функція fork Системна функція (або системний виклик) fork () створює новий процес, який являє собою дублікат викликає процесу, тобто його батька. При успішному виконанні функція fork () повертає батьківському і синівськи процесам два різних значення. Синівськи повертається число 0, а батьківському - значення PID синівської процесу. Батьківський і синівський процеси продовжують виконуватися з інструкції, безпосередньо наступної за функцією fork (). У разі невдалого виконання (воно виражається в тому, що синівський процес не був створений) батьківському процесу повертається число -1.
#include <unistd.h>
pid_t fork(void); _
Невдалий результат функції fork () можливий у випадку, якщо система не володіє ресурсами для створення ще одного процесу. Це відбувається при перевищенні обмеження (якщо воно існує) на кількість синівських процесів, яке може породжувати батько, або на кількість виконуються процесів у масштабі всієї системи. У цьому випадку встановлюється мінлива errno, яка означає наявність помилки.
Функція exit Функція exit
Системний виклик exit завершує процес. Зокрема, цей API викликає звільнення сегменту даних викликає процесу, сегментів стека і U-області і закриття всіх відкритих дескрипторів файлів. Однак запис у таблиці процесів для цього процесу залишається недоторканою, з тим щоб там реєструвався статус заверщенія процесу, а також відображалася статистика його виконання (наприклад, інформація про обшем часу виконання, кількості пересланих блоків введення-виведення даних і т.д.). Тепер процес називається зомбі-процесом, так як його виконання вже не може бути заплановано. Батьківський процес може вибрати зберігаються в запису таблиці процесів дані за допомогою системного виклику wait або waitpid. Ці API звільняють також запис у таблиці процесів, що відноситься до породженому процесу.
Якщо процес створює породжений процес і закінчується до завершення останнього, то ядро призначить процес init в якості керуючого для породженого процесу (це другий процес, створюваний після початкового завантаження ОС UNIX. Його ідентифікатор завжди дорівнює 1). Після заверщенія породженого процесу відповідний запис у таблиці процесів буде знищена процесом init.
Прототип функції exit має наступний вигляд:
# Include <unistd.h> void exit (int exit code);
Цілочисельний аргумент функції jexit - це код заверщенія процесу. Батьківському процесу передаються лише молодші 8 бітів цього коду. Код завершення Про означає успішне виконання процесу, а ненульовий код - невдале виконання. У деяких UNIX-системах в заголовку <stdio.h> визначаються символічні константи EXIT SUCCESS і EXIT FAILU-RE, які можуть бути використані як аргументи функцій exit, відповідні успішному і невдалого завершення.
Функція ех / 7 ніколи не виконується невдало, тому значення, що повертається для неї не передбачено.
Бібліотечна С-функція exit є оболонкою для exit. Зокрема, exit спочатку очищає буфери і закриває всі відкриті потоки викликає процесу. Потім вона викликає всі функції, які були зареєстровані за допомогою функції atexit (у порядку, зворотному порядку їх реєстрації), і, нарешті, викликає exit для завершення процесу.
У наведеній нижче програмі test exit. З демонструється використання функції exit. Коли програма запускається, вона оголошує про своє існування і потім завершується допомогою виклику exit. Для позначення успішного виконання програми вона передає нульове значення коду завершення.
finclude <iostream.h> finclude <unistd.h> int main () {
cout Test program for exit endl;
exit (0);
return 0;
Після виконання цієї програми користувачі можуть перевірити статус її завершення з допомогою змінних status (в C-shell) або $? (У Bourne-shell). Програма може дати наступні результати:
% СС-о test exit test exit.C; test exit Test program for exit% echo $ status 0