
- •Практичне заняття 8 Організація уведення-виведення в unix. Файли пристроїв. Апаратні переривання
- •Операції над файловими системами. Монтування файлових систем
- •Блокові, символьні пристрої. Поняття драйвера. Блокові, символьні драйвери, драйвери низького рівня. Файловий інтерфейс
- •Апаратні переривання (interrupt), виключення (exception), програмні переривання (trap, software interrupt). Їх обробка
- •Поняття сигналу. Способи виникнення сигналів і види їх обробки
- •Поняття групи процесів, сеансу, лідера групи, лідера сеансу, управляючого терміналу сеансу. Системні виклики getpgrp(), setpgrp(), getpgid(), setpgid(), getsid(), setsid()
- •Системний виклик kill() і команда kill
- •Вивчення особливостей отримання термінальних сигналів поточною і фоновою групою процесів
- •Системний виклик signal(). Установка власного обробника сигналу
- •Прогін програми, що ігнорує сигнал sigint
- •Прогін програми з призначеною для користувача обробкою сигналу sigint
- •Відновлення попередньої реакції на сигнал
- •Сигнали sigusr1 і sigusr2. Використовування сигналів для синхронізації процесів
- •Завершення породженого процесу. Системний виклик waitpid(). Сигнал sigchld
- •Прогін програми для ілюстрації обробки сигналу sigchld
- •Виникнення сигналу sigpipe при спробі запису в pipe або fifo, який ніхто не збирається читати
- •Поняття про надійність сигналів. Posix функції для роботи з сигналами
- •Питання до захисту роботи
Прогін програми, що ігнорує сигнал sigint
Розглянемо наступну програму – 13–14-2.c:
/* Програма, що ігнорує сигнал SIGINT */
#include <signal.h>
int main(void){
/* Виставляємо реакцію процесу на сигнал SIGINT на ігнорування */
(void)signal(SIGINT, SIG_IGN);
/*Починаючи з цього місця, процес буде ігнорувати виникнення сигналу SIGINT */
while(1);
return 0;
}
Лістинг 13-14.2. Програма (13–14-2.c), що ігнорує сигнал SIGINT.
Прогін програми з призначеною для користувача обробкою сигналу sigint
Розглянемо тепер іншу програму – 13–14-3.c:
/* Програма з призначеною для користувача обробкою сигналу SIGINT */
#include <signal.h>
#include <stdio.h>
/* Функція my_handler – призначений для користувача обробник сигналу */
void my_handler(int nsig){
printf("Receive signal %d CTRL-C pressed\n", nsig);
}
int main(void){
/* Виставляємо реакцію процесу на сигнал SIGINT */
(void)signal(SIGINT, my_handler);
/*Начиная з цього місця, процес буде друкувати повідомлення про виникнення сигналу SIGINT */
while(1);
return 0;
}
Лістинг 13-14.3. Програма (13–14-3.c) з призначеною для користувача обробкою сигналу SIGINT.
Ця програма відрізняється від програми з розділу "Прогін програми, що ігнорує сигнал SIGINT" тим, що в ній введена обробка сигналу SIGINT призначеною для користувача функцією. Наберіть, відкомпілюйте і запустіть цю програму, перевірте її реакцію на натиснення клавіш <CTRL> і <C> і на натиснення клавіш <CTRL> і <4>.
Відновлення попередньої реакції на сигнал
Дотепер в прикладах ми ігнорували значення, що повертається системним викликом signal(). Насправді цей системний виклик повертає покажчик на попередній обробник сигналу, що дозволяє відновлювати перевизначену реакцію на сигнал. Розглянемо приклад програми 13—14-4.c, повертаючої первинну реакцію на сигнал SIGINT після 5 призначених для користувача обробок сигналу.
/* Програма з призначеною для користувача обробкою сигналу SIGINT, що повертається до первинної реакції на цей сигнал після 5 його обробок*/
#include <signal.h>
#include <stdio.h>
int i=0; /* Лічильник числа обробок сигналу */
void (*p)(int); /* Покажчик, в який буде
занесена адреса попереднього обробника сигналу */
/* Функція my_handler – призначений для користувача обробник сигналу */
void my_handler(int nsig){
printf("Receive signal %d, CTRL-C pressed\n", nsig);
i = i+1;
/* Після 5-й обробки повертаємо первинну реакцію на сигнал */
if(i == 5) (void) signal(SIGINT, p);
}
int main(void){
/* Виставляємо свою реакцію процесу на сигнал SIGINT, запам'ятовуючи адресу попереднього обробника */
p = signal(SIGINT, my_handler);
/*Начиная з цього місця, процес буде 5 разів друкувати повідомлення про виникнення сигналу SIGINT */
while(1);
return 0;
}
Лістинг 13-14.4. Програма (13—14-4.c) з призначеною для користувача обробкою сигналу SIGINT.
Наберіть, відкомпілюйте програму і запустіть її на виконання.
Сигнали sigusr1 і sigusr2. Використовування сигналів для синхронізації процесів
В операційній системі UNIX існує два сигнали, джерелами яких можуть служити тільки системний виклик kill() або команда kill, – це сигнали SIGUSR1 і SIGUSR2. Звичайно їх застосовують для передачі інформації про подію, що відбулася, від одного призначеного для користувача процесу іншому як сигнальний засіб зв'язку.
При реалізації ниток виконання в операційній системі Linux (див. семінари 6–7, починаючи з розділом "Поняття про нитку виконання (thread) в UNIX. Ідентифікатор нитки виконання. Функція pthread_self()") сигнали SIGUSR1 і SIGUSR2 використовуються для організації синхронізації між процесами, що представляють нитки виконання, і процесом-координатором в службових цілях. Тому призначені для користувача програми, що застосовують в своїй роботі нитки виконання, не можуть задіювати сигнали SIGUSR1 і SIGUSR2.