Студопедия  
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Сигнали

Читайте также:
  1. Индикатор-сигнализатор ДП-64.
  2. Работа автоматической переездной сигнализации в установленном нечетном направлении движения.
  3. сигнализации
  4. Цепи сигнализации и защиты

За умов багатозадачності виникає необхідність сповіщати процеси про події, що
відбуваються в системі або інших процесах. Найпростішим механізмом такого
сповіщення, визначеним POSIX, є сигнали. Сигнали діють на кшталт програмних
переривань: процес після отримання сигналу негайно реалізує на нього викликом
спеціальної функції - оброблювача цього сигналу (signal handler) або виконанням дії за замовчуванням для цього сигналу. Із кожним сигналом пов’язаний його
номер, що є унікальним у системі. Жодної іншої інформації разом із сигналом передано бути не може.

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

Типи сигналів

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

 

Асинхронні сигнали процес може отримувати у будь-який момент виконання:

♦ програміст може надіслати асинхронний сигнал іншому процесу, використовуючи системний виклик, який у POSIX-системах називають kill (), параметрами цього виклику є номер сигналу та ідентифікатор процесу;

♦ причиною виникнення сигналу може бути також деяка зовнішня подія (натискання користувача на певні клавіші, завершення процесу-нащадка тощо).

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

Диспозиція сигналів

На надходження сигналу процес може реагувати одним із трьох способів (спосіб
реакції процесу на сигнал називають диспозицією сигналу):

♦ викликати оброблювач сигналу;

♦ проігнорувати сигнал, який у цьому випадку «зникне» і не виконає жодної дії;

♦ використати диспозицію, передбачену за замовчуванням (така диспозиція задана для кожного сигналу, найчастіше це — завершення процесу).

Процес може задавати диспозицію для кожного сигналу окремо.

Блокування сигналів

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

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

Приклади сигналів

Назвемо сигнали, що визначені POSIX і підтримуються в Linux (у дужках поруч з ім'ям сигналу наведено його номер).

До синхронних сигналів належить, наприклад, сигнал SIGSEGV (11), який генерує система під час записування в захищену ділянку пам'яті.

До асинхронних сигналів належать:

♦ SIGHUP (1) — розрив зв'язку (наприклад, вихід користувача із системи);

♦ SIGINT і SIGQUIT (2,3) — сигнали переривання програми від клавіатури (генеруються під час натискання користувачем відповідно Ctrl+C і Ctrl+\);

♦ SIGKILL (9) — негайне припинення роботи програми (для такого сигналу не
можна змінювати диспозицію);

♦ SIGUSR1 і SIGUSR2 (10,12) — сигнали користувача, які можуть використовувати
прикладні програми;

♦ SIGTERM (15) — пропозиція програмі завершити її роботу (цей сигнал, на відміну від SIGKILL, може бути зігнорований).

Діями за замовчуванням для всіх зазначених сигналів, крім SIGSEGV, є припинення роботи програми (для SIGSEGV додатково генерується дамп пам’яті (coredump) — файл, у якому зберігається образ адресного простору процесу для наступного аналізу).

Задання диспозиції сигналів

Для задання диспозиції сигналу використовують системний виклик sigaction ().
#include <signal.h>

int sigaction(int signum. // номер сигналу

struct sigaction *action, // нова диспозиція

struct sigaction *old_action); // повернення попередньої диспозиції

Диспозицію описують за допомогою структури sigaction з такими полями:

♦ sa_handler -- покажчик на функцію-оброблювач сигналу;

♦ sa_mask — маска сигналу, що задає, які сигнали будуть заблоковані всередині
оброблювача;

♦ sa_flag — додаткові прапорці.

Обмежимося обнулінням sa_mask і sa_flag (не блокуючи жодного сигналу):
struct sigaction action = {0};

Поле sa_handler має бути задане як покажчик на оголошену раніше функцію,
що має такий вигляд:

void user_handler (int signum) {

// обробка сигналу

}

Ця функція і стає оброблювачем сигналів.

Параметр signum визначає, який сигнал надійшов в оброблювач (той самий оброблювач може бути зареєстрований для декількох сигналів кількома викликами
sigaction ()).

Після реєстрації оброблювач викликатиметься завжди, коли надійде відповідний сигнал:

#include<signal.h>

void sigint_handler (int signum) {

// обробка SIGINT

}

// ...

action.sa_handler = sіglnt_handler;
sigaction(SIGINT, &action. 0);

Якщо нам потрібно організувати очікування сигналу, то найпростішим способом є використання системного виклику pause (). У цьому разі процес переходить
у режим очікування, з якого його виведе поява будь-якого сигналу:

// задати оброблювачі за допомогою sigaction ()

pause (); // чекати сигналу


Дата добавления: 2014-12-20; просмотров: 4 | Нарушение авторских прав




lektsii.net - Лекции.Нет - 2014-2021 год. (0.042 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав