Архитектура ЭВМ. Операционные системы
FIFO (first-in-first-out)
FIFO
FIFO
FIFO
Использование системного вызова mknod() для создания FIFO
Использование системного вызова mkfifo() для создания FIFO
Особенности поведения вызова open() при открытии FIFO
Особенности поведения вызова open() при открытии FIFO
Особенности поведения вызова open() при открытии FIFO
Сигналы UNIX
Сигналы UNIX
Механизм передачи сигналов
Сигналы UNIX
Сигналы UNIX
Сигналы UNIX
69.94K
Category: programmingprogramming

Архитектура ЭВМ. Операционные системы. FIFO (first-in-first-out)

1. Архитектура ЭВМ. Операционные системы

Власов Евгений

2. FIFO (first-in-first-out)

Для организации потокового взаимодействия любых (включая
неродственные) процессов в операционной системе UNIX применяется средство связи, получившее название FIFO (от First Input First
Output) или именованный pipe.
FIFO во всем подобен pipe, за одним исключением: доступ к FIFO
процессы могут получать не через родственные связи, а через
файловую систему.

3. FIFO

Для этого при создании FIFO на диске создается файл специального
типа, обращаясь к которому процессы могут обмениваться
информацией. Для создания FIFO используется системный вызов
mknod() или существующая в некоторых версиях UNIX функция
mkfifo().
После открытия FIFO ведет себя точно так же, как и pipe. Для
дальнейшей работы с ним применяются системные вызовы
read(), write() и close().

4. FIFO

Время существования FIFO в адресном пространстве ядра
операционной системы, как и в случае с pipe, не может превышать
время жизни последнего из использовавших его процессов. Когда
все процессы, работающие с FIFO, закрывают все файловые
дескрипторы, ассоциированные с ним, система освобождает
ресурсы, выделенные под FIFO. Вся непрочитанная информация
теряется. В то же время файл-метка остается на диске и может
использоваться для новой реальной организации FIFO в
дальнейшем.

5. FIFO

ВАЖНО!
При работе этих системных вызовов не происходит
действительного выделения области адресного пространства
операционной системы под именованный pipe, а только
заводится файл-метка, существование которой позволяет
осуществить реальную организацию FIFO в памяти при его
открытии с помощью системного вызова open().
Системный вызов lseek() к FIFO не применим!

6. Использование системного вызова mknod() для создания FIFO

#include <sys/stat.h>
#include <unistd.h>
int mknod(char *path, int mode, int dev);
• Параметр dev является несущественным в нашей ситуации, и мы
будем всегда задавать его равным 0.
• Параметр path является указателем на строку, содержащую
полное или относительное имя файла, который будет являться
меткой FIFO на диске. Для успешного создания FIFO файла с
таким именем перед вызовом существовать не должно.

7.

Параметр mode устанавливает атрибуты прав доступа различных
категорий пользователей к FIFO, аналогичные атрибутам
задающим права доступа для файлов. Этот параметр задается как
результат побитовой операции «или» значения S_IFIFO и
параметра mode.
При создании FIFO реально устанавливаемые права доступа
получаются из стандартной комбинации параметра mode и маски
создания файлов текущего процесса umask, а именно – они равны
(0777 & mode) & ~umask.

8. Использование системного вызова mkfifo() для создания FIFO

#include <sys/stat.h>
#include <unistd.h>
int mkfifo(char *path, int mode);
• Параметр path является указателем на строку, содержащую
полное или относительное имя файла, который будет являться
меткой FIFO на диске. Для успешного создания FIFO файла с
таким именем перед вызовом функции не должно существовать.
• Параметр mode соответствует пqараметру mode системного
вызова mknode().

9. Особенности поведения вызова open() при открытии FIFO

Системный вызов open() при открытии FIFO также ведет себя
несколько иначе, чем при открытии других типов файлов, что
связано с возможностью блокирования выполняющих его процессов.
Если FIFO открывается только для чтения, и флаг O_NDELAY не
задан, то процесс, осуществивший системный вызов, блокируется
до тех пор, пока какой-либо другой процесс не откроет FIFO на
запись. Если флаг O_NDELAY задан, то возвращается значение
файлового дескриптора, ассоциированного с FIFO.

10. Особенности поведения вызова open() при открытии FIFO

Если FIFO открывается только для записи, и флаг O_NDELAY не
задан, то процесс, осуществивший системный вызов, блокируется
до тех пор, пока какой-либо другой процесс не откроет FIFO на
чтение. Если флаг O_NDELAY задан, то констатируется
возникновение ошибки и возвращается значение -1.
Задание флага O_NDELAY в параметрах системного вызова open()
приводит и к тому, что процессу, открывшему FIFO, запрещается
блокировка при выполнении последующих операций чтения из
этого потока данных и записи в него.

11. Особенности поведения вызова open() при открытии FIFO

Если процесс записывает данные в FIFO, с которым не
взаимодействует в режиме чтения ни один другой процесс, то ядро
посылает в него сигнал SIGPIPE, для уведомления . Если процесс
пытается прочитать данные из FIFO, с которым ни один процесс не
взаимодействует в режиме записи, то он прочитает оставшиеся
(если они там были) данные и признак конца файла. Таким
образом, если два процесса взаимодействуют через FIFO
записывающий процесс после завершения работы должен закрыть
свой дескриптор FIFO для того, чтобы читающий процесс получил
признак конца файла.

12. Сигналы UNIX

Сигналы являются программными прерываниями, которые посылаются
процессу, когда случается некоторое событие. Сигналы могут возникать
синхронно с ошибкой в приложении, например SIGFPE(ошибка
вычислений с плавающей запятой) и SIGSEGV(ошибка адресации), но
большинство сигналов является асинхронными. Сигналы могут
посылаться процессу, когда система обнаруживает программное
событие, например, когда пользователь дает команду прервать или
остановить выполнение, или сигнал на завершение от другого процесса.
Сигналы могут прийти непосредственно от ядра ОС, когда возникает
сбой аппаратных средств ЭВМ. Система определяет набор сигналов,
которые могут быть отправлены процессу. В Linux существует примерно
30 различных сигналов. При этом каждый сигнал имеет целочисленное
значение и приводит к строго определенным действиям.

13. Сигналы UNIX

Для каждого сигнала в системе определена обработка по
умолчанию, которую выполняет ядро, если процесс не указал
другого действия. В общем случае существует пять возможных
действий: завершить выполнение процесса (с создание core и без),
игнорировать сигнал, остановить процесс и продолжить процесс.

14. Механизм передачи сигналов

• Установление и обозначение сигналов в форме целочисленных значений
• Маркер в строке таблицы процессов для прибывших сигналов
• Таблица с адресами функций, которые определяют реакцию на
прибывающие сигналы.
Отдельные сигналы разделяются на три различных класса:
• Системные сигналы (ошибка аппаратуры, системная ошибка и т.д.)
• Сигналы от устройств
• Определенные пользователем сигналы
Как только сигнал приходит, он отмечается записью в таблице процессов. Если
этот сигнал определен для процесса, то по таблице указателей функций в
структуре Task определяется, как нужно реагировать на этот сигнал. При этом
номер сигнала служит индексом таблицы.

15. Сигналы UNIX

Главное отличие сигналов от других средств взаимодействия
между процессами заключается в том, что их обработка
программой обычно происходит сразу же после поступления
сигнала (или не происходит вообще), независимо от того, что
программа делает в данный момент. Сигнал прерывает
нормальный порядок выполнения инструкций в программе и
передает управление специальной функции – обработчику
сигнала.

16. Сигналы UNIX

Если обработка сигнала не приводит к завершению процесса, то после
выхода из функции-обработчика выполнение процесса возобновляется с
той точки, в которой оно было прервано. У программ также есть
возможность приостановить обработку поступающих сигналов
временно, на период выполнения какой-либо важной операции.
В традиционной терминологии приостановка получения определенных
сигналов называется блокированием. Если для поступившего сигнала
было установлено блокирование, сигнал будет передан программе, как
только она разблокирует данный тип сигналов. Этим блокирование
отличается от игнорирования сигнала, при котором сигналы
соответствующего типа никогда не передаются программе.

17. Сигналы UNIX

Не все сигналы могут быть проигнорированы. Например, при
получении программой сигнала принудительного завершения
SIGKILL система ничего не сообщает программе, а просто
прекращает ее работу. Таким образом, преимущество сигналов
перед другими средствами взаимодействия с программой
заключается в том, что посылать программе сигналы можно в
любой момент ее работы, не дожидаясь наступления каких-то
особых условий. Источником сигналов может быть как
операционная система, так и другие программы пользователя. Для
реализации сигналов действительно используются программные
прерывания.

18.

SIGABRT
6
SIGALRM
Завершение с дампом памяти
Сигнал посылаемый функцией abort()
Управление
14 Завершение
Сигнал истечения времени, заданного alarm()
Уведомление
SIGBUS
10 Завершение с дампом памяти
Неправильное обращение в физическую память
Исключение
SIGCHLD
18 Игнорируется
Дочерний процесс завершен или остановлен
Уведомление
SIGCONT
25 Продолжить выполнение
SIGFPE
SIGHUP
SIGILL
8
1
4
Завершение с дампом памяти
Завершение
Завершение с дампом памяти
Продолжить выполнение ранее остановленного
процесса
Ошибочная арифметическая операция
Закрытие терминала
Недопустимая инструкция процессора
SIGINT
SIGKILL
2
9
Завершение
Завершение
Сигнал прерывания (Ctrl-C) с терминала
Безусловное завершение
Управление
Управление
SIGPIPE
13 Завершение
Запись в разорванное соединение (пайп, сокет)
Уведомление
SIGPOLL
SIGPROF
22 Завершение
29 Завершение
Событие, отслеживаемое poll()
Истечение таймера профилирования
Уведомление
Отладка
SIGQUIT
3
Сигнал «Quit» с терминала (Ctrl-\)
Управление
SIGSEGV
SIGSTOP
11 Завершение с дампом памяти
23 Остановка процесса
Нарушение при обращении в память
Остановка выполнения процесса
Исключение
Управление
Завершение с дампом памяти
Управление
Исключение
Уведомление
Исключение

19.

SIGSTOP
23 Остановка процесса
Остановка выполнения процесса
Управление
SIGSYS
12 Завершение с дампом памяти
Неправильный системный вызов
Исключение
SIGTERM
15 Завершение
Сигнал завершения (сигнал по умолчанию
Управление
для утилиты kill)
SIGTRAP
5
Ловушка трассировки или брейкпоинт
Отладка
SIGTSTP
20 Остановка процесса
Сигнал остановки с терминала (Ctrl-Z).
Управление
SIGTTIN
26 Остановка процесса
SIGTTOU
27 Остановка процесса
SIGURG
21 Игнорируется
На сокете получены срочные данные
Уведомление
SIGUSR1
SIGUSR2
16 Завершение
17 Завершение
Пользовательский сигнал № 1
Пользовательский сигнал № 2
Пользовательский
Пользовательский
SIGVTALRM
28 Завершение
Истечение «виртуального таймера»
Уведомление
SIGXCPU
30 Завершение с дампом памяти
SIGXFSZ
31 Завершение с дампом памяти
Завершение с дампом памяти
Попытка чтения с терминала фоновым
процессом
Попытка записи на терминал фоновым
процессом
Управление
Управление
Процесс превысил лимит процессорного
Исключение
времени
Процесс превысил допустимый размер
Исключение
файла

20.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void term_handler(int i) {
printf ("Terminating\n");
exit(EXIT_SUCCESS);
}
int main(int argc, char ** argv) {
struct sigaction sa;
sigset_t newset;
sigemptyset(&newset);
sigaddset(&newset, SIGHUP);
sigprocmask(SIG_BLOCK, &newset, 0);
sa.sa_handler = term_handler;
sigaction(SIGTERM, &sa, 0);
printf("My pid is %i\n", getpid());
printf("Waiting...\n");
while(1) sleep(1);
return EXIT_FAILURE;
}

21.

sigprocmask
sigaction
sigemptyset
sigfillset
sigaddset
sigdelset
sigwait
kill
raise
блокирует/разблокирует набор сигналов; каждый поток
потоки независимо друг от друга
устанавливает обработчик сигнала; действительны для всей
программы в целом
инициализирует набор сигналов пустыми значениями
устанавливает все возможные значения в наборе
добавляет значение сигнала в набор
удаляет сигнал из набора
ожидает появление одного из заданных сигналов. программа
приостановлена в ожидании некоторых сигналов,
обработчики всех не заблокированных и не игнорируемых
сигналов выполняются обычным образом
Посылка сигнала любому процессу
посылка сигнала самому себе
English     Русский Rules