Пример. Совместное использование сигналов и каналов – «пинг-понг».
Следующий пример - совместное использования сигналов и каналов.
Каналы, как правило, используются как однонаправленное средство. Но их можно использовать и как двунаправленное средство, т.е. для реализации передачи данных в обоих направлениях, но в этом случае понадобятся дополнительные средства синхронизации. Средством синхронизации являются сигналы. Здесь процессы посылают друг другу число, всякий раз увеличивая его на 1, и когда число достигнет определенного максимума, оба процесса завершаются, т.е. фактически они передают друг другу это число определенное количество раз. Средой передачи данных служит канал, средством синхронизации для того, чтобы осуществить двустороннюю передачу данных служит сигнал. Здесь определяется константа максимального значения числа, после которого нужно выйти.
Первым делом смотрим на обработчик сигнала. Обработчик сигнала, в данном случае будет использоватьcя сигнал SIGUSER1 для синхронизации, т.е. посылать его процессу всякий раз когда пришла его очередь читать из канала, т.к. взаимные скорости выполнения отца и сына неизвестны. SIGUSER1 - это сигнал, который не соответствует какому-либо определенному событию в ОС, а его семантика определяется пользователями, т.е. это как раз тот случай, когда семантика сигнала отдается на усмотрение программисту.
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_CNT 100
int target_pid, cnt;
int fd[2];
int status;
void SigHndlr(int s)
{
/* в обработчике сигнала происходит и чтение, и запись */
signal(SIGUSR1, SigHndlr);
if (cnt < MAX_CNT)
{
read(fd[0], &cnt, sizeof(int));
printf("%d \n", cnt);
cnt++;
write(fd[1], &cnt, sizeof(int));
/* посылаем сигнал второму: пора читать из канала */
kill(target_pid, SIGUSR1);
}
else
if (target_pid == getppid())
{
/* условие окончания игры проверяется потомком */
printf("Child is going to be terminated\n");
close(fd[1]); close(fd[0]);
/* завершается потомок */
exit(0);
} else
kill(target_pid, SIGUSR1);
}
int main(int argc, char **argv)
{
pipe(fd); /* организован канал */
signal (SIGUSR1, SigHndlr);
/* установлен обработчик сигнала для обоих процессов */
cnt = 0;
if (target_pid = fork())
{
/* Предку остается только ждать завершения потомка */
while(wait(&status) == -1);
printf("Parent is going to be terminated\n");
close(fd[1]); close(fd[0]);
return 0;
}
else
{
/* процесс-потомок узнает PID родителя */
target_pid = getppid();
/* потомок начинает пинг-понг */
write(fd[1], &cnt, sizeof(int));
kill(target_pid, SIGUSR1);
for(;;); /* бесконечный цикл */
}
}
Процесс – сын начинает игру. Во-первых, устанавливается target_pid, который в процессе-отце был установлен в fork(), в процессе-сыне он устанавливается с помощью вызова getppid(), который возвращает pid по требованию. И он записывает текущее значение в канал и посылает сигнал SIGUSR1 своему предку. Далее происходит бесконечный цикл. Т.е. вся обработка «пинг-понг», которая заключается в чтении данных из канала, увеличения на 1, проверки значения (не достигло ли оно своего максимума) и записи нового увеличенного значения в канал – все это происходит в обработчике канала, т.е. здесь функция main() в процессе-сыне - бесконечный цикл, а в процессе – отце wait() – ожидание завершения потомка. Процесс-сын завершается когда нашел максимум, а процесс-отец в этом случае выходит из wait(), закрывает канал и тоже выходит.
Неименованные каналы являются достаточно мощным средством передачи данных, однако, у них имеется важный недостаток, о котором уже говорилось, а именно то, что они доступны только родственным процессам. Т.е. поскольку к ним не возможен доступ по имени, а возможен только с помощью файловых дескрипторов, то нужно сначала породить канал, затем породить потомков и только таким образом они могут унаследовать дескрипторы записи и чтения в канал. Это важное ограничение, поскольку два не связанных между собой процесса, которые были порождены ранее, чем средства межпроцессного взаимодействия канал не могут использовать. Эту проблему решает средство - именованные каналы
- Конспект по курсу лекций Операционные системы
- Структура вычислительной системы
- Аппаратный уровень вычислительной системы
- Системы программирования
- Модель организации прерываний с использованием регистра «слово состояние процессора»
- 3.6.1.1 Устройство последовательного доступа
- Организация управления внешними устройствами
- Иерархия памяти
- Аппаратная поддержка ос и систем программирования
- Некоторые проблемы
- 1. Вложенные обращения к подпрограммам
- 2. Накладные расходы при смене обрабатываемой программы:
- 4. Фрагментация памяти
- 4.2.1 Регистровые окна ( register window )
- Системный стек
- Виртуальная память.
- Базирование адресов.
- Страничная память.
- Многомашинные, многопроцессорные ассоциации.
- Терминальные комплексы
- Компьютерные сети.
- Семейство протоколов tcp/ip
- Ip адрес представляется последовательностью четырех байтов. В адресе кодируется уникальный номер сети, а также номер компьютера (сетевого устройства в сети).
- Транспортный уровень
- Уровень прикладных программ
- Сетевые, распределенные ос
- Операционные системы Основные понятия
- Структура ос.
- Модельная ос
- Жизненный цикл процесса
- Типы операционных систем
- Системы разделения времени
- Управление внешними устройствами. Архитектура.
- Программное управление внешними устройствами
- Буферизация обмена
- Планирование дисковых обменов
- Raid системы.
- Файлы устройств, драйверы
- Управление оперативной памятью
- Двухуровневая организация
- Структурная организация файлов
- Атрибуты файла
- Типовые программные интерфейсы работы с файлами
- Подходы в практической реализации файловой системы Структура «системного» диска
- Модели реализации файлов Непрерывные файлы
- Файлы, имеющие организацию связанного списка.
- Индексные узлы (дескрипторы)
- Модели организации каталогов
- Варианты соответствия: имя файла – содержимое файла
- Координация использования пространства внешней памяти
- Учет свободных блоков файловой системы Связный список свободных блоков
- Использование битового массива
- Организация фс Unix
- Логическая структура каталогов
- Внутренняя организация фс Модель версии System V Структура фс
- Работа с массивами номеров свободных блоков
- Работа с массивом свободных ид
- Индексные дескрипторы
- Адресация блоков файла
- Файл каталог
- Установление связей
- Недостатки фс модели версии System V
- Модель версии ffs bsd
- Стратегии размещения
- Внутренняя организация блоков
- Структура каталога ffs
- Понятие «процесс».
- Процессы в ос Unix Системно-ориентированное определение процесса
- Базовые средства организации и управления процессами
- Семейство системных вызовов exec()
- Использование схемы fork-exec
- Формирование процессов 0 и 1
- . Планирование Основные задачи планирования
- Планирование очереди процессов на начало обработки
- Кванты постоянной длины.
- Кванты переменной длины
- Класс подходов, использующих линейно возрастающий приоритет.
- Разновидности круговорота.
- Смешанные алгоритмы планирования
- Планирование в системах реального времени
- Общие критерии для сравнения алгоритмов планирования
- Планирование в ос unix
- Планирование в Windows nt.
- Планирование свопинга в ос Unix
- Взаимодействие процессов: синхронизация, тупики Параллельные процессы
- Проблемы организации взаимного исключения
- Тупики (deadlocks)
- Способы реализации взаимного исключения
- Семафоры Дейкстры
- Мониторы
- Обмен сообщениями
- Классические задачи синхронизации процессов
- Задача «читателей и писателей»
- Задача о «спящем парикмахере»
- Реализация взаимодействия процессов
- Сигналы
- Системный вызов kill()
- Системный вызов signal()
- Пример 1.
- Пример 2.
- 5 Пример. Программа “Будильник”.
- Пример. Двухпроцессный вариант программы “Будильник”.
- Пример. Использование канала.
- Пример. Схема взаимодействия процессов с использованием канала.
- Пример. Реализация конвейера.
- Пример. Совместное использование сигналов и каналов – «пинг-понг».
- Именованные каналы. Особенность именованных каналов в ос Unix.
- Пример. «Клиент-сервер».
- Межпроцессное взаимодействие, проводимое по модели «главный-подчинённый».
- Системный вызов ptrace()
- Общая схема трассировки процессов
- Пример. Использование трассировки.
- Система межпроцессного взаимодействия ipc.
- Очередь сообщений
- Системный вызов msgget()
- Функция msgsnd()
- Функция msgrcv()
- Функция msgctl()
- Пример. Использование очереди сообщений.
- Пример. Очередь сообщений. Модель «клиент-сервер».
- Разделяемая память.
- Пример. Работа с общей памятью в рамках одного процесса.
- Семафоры
- Пример. Использование разделяемой памяти и семафоров.
- 1Й процесс:
- 2Й процесс:
- Механизм сокетов
- Типы сокетов.
- Функция создания сокета
- Запрос на соединение
- Прослушивание сокета
- Подтверждение соединения
- Прием и передача данных
- Закрытие сокета
- Пример. Работа с локальными сокетами
- Пример работы с сокетами в рамках сети.