Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PR_СП_лекции_укр.doc
Скачиваний:
6
Добавлен:
22.04.2019
Размер:
697.34 Кб
Скачать

3.5.6 Очікування сигналу

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

int pause()

Функція припиняє виконання програми до приходу сигналу, що викликає виконання оброблювача або переривання виконання процесу.

Якщо сигнал викликає оброблювач, то функція завжди повертає значення -1, а errno приймає наступне значення: EINTR Функція перервана приходом сигналу.

У випадку припинення виконання процесу функція не повертає ніякого значення. Функція визначена в заголовному файлі <unistd.h>.

Однак, при використанні цієї функції виникає серйозна проблема безпеки роботи програми. pause безпечно може бути використана тільки в програмі, що в основному тілі програми тільки викликає саму функцію pause, а всю корисну роботу виконує оброблювач події. Наприклад, у наступному фрагменті програми

/* 'usr_interrupt' установлюється оброблювачем сигналу. */

if (!usr_interrupt)

pause ();

/* Виконується робота, при приході сигналу. */

...

Сигнал може надійти після того, як перевірена змінна, але до виклику pause. Якщо більше не надійде жодного сигналу, програма ніколи не відновить працездатність.

Можна встановити максимальний час очікування за допомогою функції sleep:

while (!usr_interrupt)

sleep (1);

...

Однак, і такий спосіб підходить не у всіх випадках. Найбільш безпечним способом очікування сигналу є використання функції sigsuspend:

int sigsuspend(sigset_t *SET)

Функція заміняє маску сигналів процесу й припиняє його роботу до надходження одного із сигналів, що не заблокований маскою. Маска, що задається SET діє тільки на час очікування, викликуваному функцією, після повернення керування процесу відновлюється стара маска сигналів. Використання sigsuspend у наступному прикладі абсолютно безпечно:

sigset_t mask, oldmask;

...

/* Установлюється маска сигналів. */

sigemptyset (&mask);

sigaddset (&mask, SIGUSR1);

...

/* Очікується прихід сигналів. */

sigprocmask (SIG_BLOCK, &mask, &oldmask);

while (!usr_interrupt)

sigsuspend (&oldmask);

sigprocmask (SIG_UNBLOCK, &mask, NULL);

3.6 Трасування процесу.

Це найбільш примітивна форма межпроцессорного взаємодії, особливо важлива при налагодженні. Головним тут є відношення " засипання-пробудження" між контрольованим і контролюючим процесами (завжди " батько-дитина"). Трасується завжди процес-дитина; здійснюється це через системний виклик ptrace(), що використовує сигнали перемикання від батька до ребенку й навпаки.

3.7 Канали й fifo-Файли

3.7.1 Поняття

Канал (неіменований) - це один з механізмів UNIX, призначений для зв'язку між процесами. Дані, записані в канал одним процесом можуть бути лічені іншим процесом. Дані надходять у канал і видаються з нього в порядку “першим прийшов, першим вийшов”. Канал не має ім'я й створюється для однократного використання.

FIFO-Файли (пойменовані канали) схожі з каналами, але на відміну від каналів вони не є тимчасовими з'єднаннями між процесами й мають одне або кілька імен як у будь-якого файлу операційної системи. Процеси відкривають FIFO-Файл використовуючи його ім'я.

Канали й FIFO-Файли повинні бути відкриті двома взаємодіючими процесами незалежно. При читанні з каналу або FIFO-Файлу, у який жоден потік не записує дані (наприклад, якщо файл або канал уже був закритий), операція читання повертає символ кінця файлу. Запис у канал, що не має жодного процесу, що виконує операцію читання трактується як помилка й генерує сигнал SIGPIPE і завершується з кодом помилки, рівним EPIPE, якщо сигнал обробляється або заблокований.

Ні канали ні FIFO-Файли не мають механізму присохлого покажчика. І читання й запис здійснюються послідовно. Читання виконується з початку файлу, запис - у кінець файлу.

Системний виклик pipe() використовується для створення й ініціювання непойменованих каналів, mknod() дозволяє створювати файли з методом доступу FIFO.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]