Н.В. Вдовикина, И.В. Машечкин, А.Н. Терехин, В.В. Тюляева - Программирование в ОС UNIX на языке Си (1114655), страница 12
Текст из файла (страница 12)
Кроме того, зарезервирован один или несколько номеров сигналов, семантика которыхопределяется пользовательскими процессами по своему усмотрению(например, процессы могут посылать друг другу сигналы с цельюсинхронизации).Количество различных сигналов в современных версиях UNIXоколо 30, каждый из них имеет уникальное имя и номер. Описанияпредставлены в файле <signal.h>.
В таблице ниже приведено несколько примеров сигналов14:Числовое зна- Константа Значение сигналачение2SIGINTПрерывание выполнения по нажатиюCtrl-C3SIGQUIT Аварийное завершение работы9SIGKILL Уничтожение процесса14SIGALRM Прерывание от программного таймера14Следует заметить, что в разных версиях UNIX имена сигналов могут различаться.73SIGCHLD Завершился процесс-потомокСигналы являются механизмом асинхронного взаимодействия,т.е. момент прихода сигнала процессу заранее неизвестен.
Однакопроцесс может предвидеть возможность получения того или иногосигнала и установить определенную реакцию на его приход. В этомплане сигналы можно рассматривать как программный аналог аппаратных прерываний.При получении сигнала процессом возможны три варианта реакции на полученный сигнал:18- процесс реагирует на сигнал стандартным образом, установленным по умолчанию (для большинства сигналов действие по умолчанию – это завершение процесса);- процесс может заранее установить специальный способ обработки конкретного сигнала, в этом случае по приходуэтого сигнала вызывается функция-обработчик, определенная процессом (при этом говорят, что сигнал перехватывается);- процесс может проигнорировать сигнал.Для каждого сигнала процесс может устанавливать свой вариант реакции, например, некоторые сигналы он может игнорировать,некоторые перехватывать, а на остальные установить реакцию поумолчанию.
При этом по ходу своей работы процесс может изменятьвариант реакции на тот или иной сигнал. Однако, некоторые сигналы невозможно ни перехватить, ни игнорировать. Они используютсяядром ОС для управления работой процессов (например, SIGKILL,SIGSTOP).Если в процесс одновременно доставляется несколько различных сигналов, то порядок их обработки не определен.
Если же обработки ждут несколько экземпляров одного и того же сигнала, то ответ на вопрос, сколько экземпляров будет доставлено в процесс – всеили один – зависит от конкретной реализации ОС.В любом случае, в момент прихода сигнала, для которого задана пользовательская функция-обработчик, нормальное выполнение процесса прерывается, и управление переходит на точку входаобработчика сигнала. По выходу из функции-обработчика выполнение процесса возобновляется с той точки, на которой оно было прервано.Ситуация, когда сигнал приходит в момент выполнения системного вызова, в разных версиях UNIX обрабатывается по-разному:например, обработка сигнала может быть отложена до завершениясистемного вызова; либо системный вызов автоматически переза-74пускается после его прерывания сигналом; либо системный вызоввернет –1, а в переменной errno будет установлено значение EINTR.Для отправки сигнала служит системный вызов int kill(pid_t pid, int sig).Первым параметром вызова служит идентификатор процесса, которому посылается сигнал (процесс можетпослать сигнал и самому себе).
Если значение первого параметраесть 0, сигнал будет передан всем процессам, которые принадлежаттой же группе, что и процесс, посылающий сигнал, за исключениемпроцессов с идентификаторами 0 и 1.Во втором параметре передается номер посылаемого сигнала.Если этот параметр равен 0, то будет выполнена проверка корректности обращения к kill() (в частности, существование процесса сидентификатором pid), но никакой сигнал в действительности посылаться не будет.Если процесс-отправитель не обладает правами привилегированного пользователя, то он может отправить сигнал только темпроцессам, у которых реальный или эффективный идентификаторвладельца процесса совпадает с реальным или эффективным идентификатором владельца процесса-отправителя.Для определения реакции на получение того или иного сигнала в процессе служит системный вызов void (*signal ( int sig,void (*disp) (int))) (int).
Аргумент sig — номер сигнала,для которого устанавливается реакция, а disp — либо определеннаяпользователем функция-обработчик сигнала, либо одна из констант:SIG_DFL (установить для данного сигнала обработку по умолчанию,т.е. стандартную реакцию системы) и SIG_IGN (игнорировать данный сигнал). При успешном завершении функция возвращает указатель на предыдущий обработчик данного сигнала (он может использоваться процессом, например, для последующего восстановленияпрежней реакции на сигнал).Определенная пользователем функция-обработчик сигналадолжна принимать один целочисленный аргумент (в нем будет передан фактический номер обрабатываемого сигнала, что позволяетиспользовать один обработчик для разных сигналов), и не возвращать никаких значений.В ранних версиях UNIX: каждый раз в момент получения сигнала его диспозиция (т.е. способ реакции на сигнал) сбрасывалась вдействие по умолчанию, т.о.
если процесс желал многократно обрабатывать сигнал своим собственным обработчиком, он должен былкаждый раз при обработке сигнала заново устанавливать реакцию нанего.75Задача 2. Написать программу, которая завершается на пятоенажатие комбинации клавиш Ctrl-C.#include <sys/types.h>#include <signal.h>#include <stdio.h>int count = 1;void SigHndlr (int s)/* обработчик сигнала */{printf("\n I got SIGINT %d time(s) \n",++ count);if (count == 5) signal (SIGINT, SIG_DFL);/* ставим обработчик сигнала по умолчанию */else signal (SIGINT, SigHndlr);/* восстанавливаем обработчик сигнала */}int main(int argc, char **argv){signal (SIGINT, SigHndlr); /* установка реакции насигнал */while (1); /*”тело программы” */return 0;}Задача 3.
Реализовать игру «пинг-понг» между двумя процессами (процессы посылают друг другу целое число, всякий раз увеличивая его на 1, и когда число достигнет некоего максимума, обапроцесса завершаются), используя лишь один канал.Данная программа дает пример использования каналов и сигналов для осуществления связи между процессами – весьма типичной ситуации в системе. При этом канал играет роль среды двусторонней передачи информации, но при таком его использовании процессам требуется дополнительное средство синхронизации для определения очередности чтения/записи в канал. Таким средствомсинхронизации будут сигналы.#include#include#include#include#include#include<signal.h><sys/types.h><sys/wait.h><unistd.h><stdlib.h><stdio.h>#define MAX_CNT 100int target_pid, cnt;int fd[2];int status;void SigHndlr(int s)76{/* в обработчике сигнала происходит и чтение, изапись */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);}elseif (target_pid == getppid()){/* условие окончания игры проверяется потомком */printf("Child is going to be terminated\n");close(fd[1]); close(fd[0]);/* завершается потомок */exit(0);} elsekill(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(;;); /* бесконечный цикл */77}}Упражнения1.
Написать программу, реализующую следующую команду Shell:a. pr1 arg1 arg2 | pr2; pr3>>f1.datb. pr1<f1.dat | pr2>f2.dat; pr3c. pr1 | pr2 | . . . | prnd. pr1 arg1>f1.dat; pr2 | pr3 | pr4>>f1.dat, где pr i – имена исполняемых файлов, а f i .dat – имена файловданных. Имена в указанном порядке задаются вкомандной строке.2. Написать программу, обрабатывающую каждое четноевозникновение сигнала SIGTRAP формированием двухсыновних процессов, связанных каналом. Завершитьработу по 3-му нажатию CTRL+C.3. Написать программу подсчета поступивших сигналовSIGTRAP между 2-ым и 4-ым нажатием CTRL+C.Завершить работу по 7-му нажатию CTRL+C.4. Написать программу параллельного поиска подстроки вфайлах, имена которых заданы в командной строке. Поиск подстроки в каждом из заданных файлов организовать в процессе – потомке, создав для каждого файласвой процесс.
Программа завершается, как только подстрока будет найдена в одном из файлов. Все незавершенные процессы должны быть прерваны.5. Написать программу слияния двух файлов в третий.Файл-результат формируется чередованием отрезков поN символов из первого и второго файлов (если один изфайлов длиннее другого, то его оставшаяся часть приписывается в конец файла-результата).
Имена файлов и величина N задаются в командной строке. Исходные файлы читаются разными процессами; эти же процессы поочереди записывают по N байт из обрабатываемых имифайлов в файл-результат. Синхронизацию их работы организовать с помощью сигналов.6. Написать программу копирования содержимого одногофайлавдругой.Копированиеосуществляетвспомогательный процесс. Если во время копированиявстретилась строка, длина которой больше N, этотпроцесс сообщает процессу-родителю о такой ситуации.78Головной процесс запрашивает у пользователя, чтоделать с этой строкой:D – не записывать строку в формируемый файл;С – записать только первые N символов;А – прекратить копирование;и сообщает вспомогательному процессу о принятом решении.Головной процесс ждет окончания работы, сообщает пользователю отом, что копирование завершено, и завершается сам. Имена файлови величина N задаются в командной строке.79ТЕМА 12. Средства межпроцессного взаимодействия System VРассматриваемую в этой главе группу средств межпроцессного взаимодействия называют System V IPC (interprocess communication), так как изначально эти средства были реализованы именно вUNIX System V, однако к настоящему моменту они включены практически во все версии UNIX.System V IPC включает в себя очереди сообщений, семафоры, разделяемую память.Именование разделяемых объектовДля всех средств IPC приняты общие правила именованияобъектов, позволяющие процессу получить доступ к такому объекту.Для именования объекта IPC используется ключ, представляющийсобой целое число.