sem13 - Сигналы (Мини-учебник с ejudge = Чернокнижка), страница 4

PDF-файл sem13 - Сигналы (Мини-учебник с ejudge = Чернокнижка), страница 4 Практика расчётов на ПЭВМ (37199): Книга - 3 семестрsem13 - Сигналы (Мини-учебник с ejudge = Чернокнижка) - PDF, страница 4 (37199) - СтудИзба2019-05-08СтудИзба

Описание файла

Файл "sem13 - Сигналы" внутри архива находится в папке "Мини-учебник с ejudge = Чернокнижка". PDF-файл из архива "Мини-учебник с ejudge = Чернокнижка", который расположен в категории "". Всё это находится в предмете "практика расчётов на пэвм" из 3 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Просмотр PDF-файла онлайн

Текст 4 страницы из PDF

Если указан флаг SA_RESTART, прерванный системный вызовбудет автоматически перезапущен, а если флаг не указан, системный вызов завершится сошибкой EINTR.1.7 Блокирование сигналовВременная блокировка сигнала с помощью sigprocmask позволяет предотвратитьпрерывание нормальной работы процесса в критической секции кода. Если сигнал поступит процессу в это время, он будет доставлен позднее, когда процесс его разблокирует.Временная блокировка может быть полезна, когда и обработчик сигнала, и основная программа работают с некоторой разделяемой структурой данных (в примере выше — это функция printf, которая работает с дескриптором потока stdout).

Если работа с этой структурой не атомарна, обработчик сигнала может быть запущен, когда структура находится внецелостном состоянии, что может приводить к самым неприятным последствиям. Чтобыпредотвратить прерывание программы в момент модификации разделяемой структуры, критическая секция кода должна быть защищена командами блокирования опасного сигнала.Кроме того, сигнал должен блокироваться, когда программа должна выполнить некоторое действие только тогда, когда сигнал не пришёл. В противном случае программа будетсодержать временну́ю ошибку (timing error).

Пример такой программы будет разобран нижев разделе, посвящённом ожиданию прихода сигнала.Множество сигналов, которые в текущий момент заблокированы процессом, называется маской сигналов процесса. Каждый процесс имеет свою маску сигналов. Когда вызовомfork() создаётся новый процесс, он наследует маску сигналов родительского процесса.Функция sigprocmask позволяет изменить маску сигналов процесса.int sigprocmask(int mode,const sigset_t *pset,sigset_t *poldset);Аргумент mode задаёт, какая операция будет выполнена с маской сигналов.

Он должен бытьравен одному из следующих значений:13Множество сигналов, на которое указывает pset, добавляется к маскесигналов процесса.SIG_UNBLOCK Множество сигналов, на которое указывает pset, удаляется из маскисигналов процесса. Допускается удалить из маски неблокируемый сигнал.SIG_SETMASK Маска сигналов копируется из множества сигналов, на которое указывает pset.Если указатель poldset не равен NULL, то по этому адресу копируется старое значениемаски сигналов процесса. Если нужно только узнать текущую маску процесса, но не изменять её, аргумент pset можно задать равным NULL.Следующий пример блокирует сигнал SIGINT на время выполнения функции printf.SIG_BLOCK#include <stdio.h>#include <signal.h>int cnt = 0;void sigint_handler(int signo){printf("Ctrl-C pressed\n");if (++cnt == 3) {signal(SIGINT, SIG_DFL);raise(SIGINT);}}int main(void){sigset_t blockset;sigemptyset(&blockset);sigaddset(&blockset, SIGINT);signal(SIGINT, sigint_handler);while (1) {sigprocmask(SIG_BLOCK, &blockset, 0);printf("Some string to print\n");sigprocmask(SIG_UNBLOCK, &blockset, 0);}return 0;}1.8 Ожидание прихода сигналовПростейший способ приостановить выполнение процесса до поступления сигнала заключается в использовании функции pause.#include <unistd.h>int pause(void);Функция pause приостанавливает выполнение процесса до поступления сигнала, который не блокируется и не игнорируется.

Если сигнал обрабатывается по умолчанию, он дол14жен вызывать завершение работы процесса. Если поступление сигнала запускает функциюобработки сигнала, которая возвращает управление в процесс, функция pause возвращается с кодом завершения -1 и кодом ошибки EINTR даже в случае, когда включена семантикаперезапускаемых системных вызовов.Однако кажущаяся простота этой функции может приводить к серьёзным ошибкам. Рассмотрим программу, которая при поступлении сигнала SIGINT печатает сообщение. Возможный вариант этой программы представлен ниже:#include <stdio.h>#include <signal.h>#include <unistd.h>void sigint_handler(int signo){}int main(void){signal(SIGINT, sigint_handler);while (1) {pause();printf("Ctrl-C pressed\n");}return 0;}Эта программа содержит временну́ю ошибку (timing error).

Предположим, что сигналпоступит в момент, когда программа выполняет оператор printf. В этом случае, когдауправление вернётся на вызов pause, сигнал будет уже обработан, и функция pause «повиснет» на неопределённое время. Сигнал был потерян.Программа может быть модифицирована так, что обработчик сигнала устанавливаетнекоторую переменную, которая потом проверяется в основном цикле.#include <stdio.h>#include <signal.h>#include <unistd.h>volatile int flag;int cnt;void sigint_handler(int signo){flag = 1;}int main(void){signal(SIGINT, sigint_handler);while (1) {if (!flag) pause();flag = 0;printf("Ctrl-C pressed\n");15}return 0;}Модифицированная программа на самом деле содержит ту же самую ошибку, только вболее завуалированной форме.

Предположим, что сигнал поступил в тот момент, когда значение переменной flag уже было проверено, но функция pause ещё не была вызвана. Вэтом случае сигнал будет потерян, и программа опять зависнет на неопределённое время. Чтосамое неприятное, такая ошибка может проявлять себя крайне редко и практически невоспроизводима.Корректный способ ждать прихода сигнала реализуется с использованием функцииsigsuspend.int sigsuspend(const sigset_t *pset);Функция заменяет маску сигналов процесса маской, на которую указывает аргумент pset,затем приостанавливает выполнение процесса до поступления сигнала, который либо вызывает завершение процесса, либо обрабатывается процессом.Если сигнал обрабатывается процессом, и обработчик возвращает управление в процесс,функция sigsuspend также возвращается, при этом восстанавливается маска сигналовпроцесса, которая была на момент вызова функции.Программа, корректно ожидающая поступления сигнала SIGINT, приведена ниже.#include <stdio.h>#include <signal.h>#include <unistd.h>volatile int flag;int cnt;void sigint_handler(int signo){flag = 1;}int main(void){sigset_t mask, oldmask;sigemptyset(&mask);sigaddset(&mask, SIGINT);signal(SIGINT, sigint_handler);while (1) {sigprocmask(SIG_BLOCK, &mask, &oldmask);while (!flag)sigsuspend(&oldmask);flag = 0;sigprocmask(SIG_UNBLOCK, &mask, NULL);printf("Ctrl-C pressed\n");}return 0;16}Обратите внимание, что значение переменной flag сбрасывается в 0 при заблокированном сигнале, так как в противном случае сигнал может поступить в процесс в момент, когдасигнал уже разблокирован, но переменная flag ещё не сброшена.

Сигнал в этом случаебудет потерян.1.9 Слияние сигналовРассмотрим следующий пример:#include <stdio.h>#include <signal.h>#include <unistd.h>void sigint_handler(int signo){printf("Ctrl-C pressed\n");}int main(void){sigset_t mask;sigemptyset(&mask);sigaddset(&mask, SIGINT);signal(SIGINT, sigint_handler);while (1) {sigprocmask(SIG_BLOCK, &mask, NULL);sleep(2);sigprocmask(SIG_UNBLOCK, &mask, NULL);}return 0;}Вызов sleep здесь заменяет некоторую операцию, требующую значительного времени.Сколько бы раз в процесс не поступил сигнал SIGINT в то время, пока он заблокирован, обработчик сигнала будет вызван после разблокировки не более одного раза. Ядро неподдерживает очередь сигналов, ожидающих доставки, а хранит для каждого типа сигнала единственный бит, означающий наличие недоставленного сигнала соответствующего типа.

Эти биты все вместе образуют маску сигналов процесса, ожидающих доставки. Поэтомусигналы не могут использоваться там, где необходимо считать количество их поступлений. Вэтом случае необходимо использовать другой механизм межпроцессного взаимодействия.В современных системах введён новый тип сигналов — сигналы реального времени, длякоторых ядро поддерживает очередь ожидающих доставки сигналов, но традиционные сигналы, рассмотренные в этом документе к ним не относятся.171.10 Пример программыРассмотрим следующую программу. Два процесса обмениваются друг с другом сообщениями в стиле пинг-понг, то есть первый посылает второму число 1, на что второй отвечаетпервому числом 2, и так далее.

Для обмена данными используется единственный канал, апроцессы синхронизуются посылкой друг другу сигнала SIGUSR1. Главный процесс породит два подпроцесса, которые и будут обмениваться данными, а он сам будет просто ожидатьзавершения обоих процессов.Первая проблема, которая возникает, как передать каждому процессу идентификатордругого процесса. Мы обойдем ее поместив оба процесса в одну группу процессов. Каждыйпроцесс будет посылать сигнал SIGUSR1 всей группе процессов.#include#include#include#include#include<stdio.h><signal.h><unistd.h><stdlib.h><sys/wait.h>volatile int flag;void handler(int signo){flag = 1;}void do_work(int pgid, int sig, int *p){sigset_t bs, os, b2;intval;sigemptyset(&bs);sigaddset(&bs, SIGUSR1);sigaddset(&bs, SIGUSR2);sigemptyset(&b2);sigaddset(&b2, SIGINT);sigaddset(&b2, SIGTERM);sigprocmask(0, NULL, &os);while (1) {/* ожидаем прихода либо SIGUSR1, либо SIGUSR2 *//* так как один из них игнорируется, мы всегда получим нужный */sigprocmask(SIG_BLOCK, &bs, NULL);while (!flag)sigsuspend(&os);flag = 0;sigprocmask(SIG_UNBLOCK, &bs, NULL);read(p[0], &val, sizeof(val));/* мы не хотим, чтобы нас прервали на середине печати */sigprocmask(SIG_BLOCK, &b2, NULL);printf("Process %d got value %d\n", getpid(), val);fflush(stdout);sigprocmask(SIG_UNBLOCK, &b2, NULL);val++;18write(p[1], &val, sizeof(val));kill(-pgid, sig);}}int main(void){int pid1, pid2;int pgid;int p[2];int val = 0;pgid = getpid();signal(SIGUSR1, handler);signal(SIGUSR2, SIG_IGN);if (pipe(p) < 0) { perror("pipe"); exit(1); }if ((pid1 = fork()) < 0) { perror("fork"); exit(1); }if (!pid1) {setpgid(0, pgid);do_work(pgid, SIGUSR2, p);_exit(0);}setpgid(pid1, pgid);signal(SIGUSR1, SIG_IGN);signal(SIGUSR2, handler);if ((pid2 = fork()) < 0) { perror("fork"); exit(1); }if (!pid2) {setpgid(0, pgid);do_work(pgid, SIGUSR1, p);_exit(0);}setpgid(pid2, pgid);write(p[1], &val, sizeof(val));close(p[0]); close(p[1]);signal(SIGUSR2, SIG_IGN);kill(-pgid, SIGUSR1);sleep(1);signal(SIGTERM, SIG_IGN);kill(-pgid, SIGTERM);wait(0); wait(0);return 0;}Обратите внимание, как основная программа последовательно переустанавливает обработчики сигналов SIGUSR1 и SIGUSR2.

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

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5285
Авторов
на СтудИзбе
418
Средний доход
с одного платного файла
Обучение Подробнее