Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Теперь посмотрим, что происходит внутри цикла. Основная идея описана ниже.
1. Если это финальный процесс в задании, убедиться, что nextout
указывает на stdout. В противном случае нужно подключить вывод этого задания к входному концу неименованного канала.
2. Породить новый процесс. Внутри дочернего перенаправить stdin и stdout, как указано с помощью nextin
, nextout
и всех специфицированных ранее перенаправлений.
3. Вернувшись обратно в родительский процесс, закрыть nextin
и nextout
, используемые только что запущенным дочерним процессом (если только они не являются потоками ввода и вывода самой оболочки).
4. Теперь настроить следующий процесс в задании для приема его ввода из вывода процесса, который мы только что создали (через nextin
).
Вот как эти идеи перевести на С.
365: nextin=0, nextout=1;
366: for (i=0; i
367: if ((i+1) < newJob.numProgs) {
368: pipe(pipefds);
369: nextout = pipefds[1];
370: } else {
371: nextout = 1;
372: }
373:
374: if (!(newJob.progs[i].pid = fork())) {
375: if (nextin != 0) {
376: dup2(nextin, 0);
377: close(nextin);
378: }
379:
380: if (nextout != 1) {
381: dup2(nextout, 1);
382: close(nextout);
383: }
384:
385: /* явное перенаправление перекрывает каналы */
386: setupRedirections(newJob.progs+i);
387:
388: execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
389: fprintf(stderr, "exec() of %s failed: %s\n",
390: newJob.progs[i].argv[0],
391: strerror(errno));
392: exit(1);
393: }
394:
395: /* поместить наш дочерний процесс в группу процессов,
396: чей лидер - первый процесс канала */
397: setpgid(newJob.progs[i].pid, newJob.progs[0].pid);
398:
399: if (nextin != 0) close(nextin);
400: if (nextout != 1) close (nextout);
401:
402: /* Если больше нет процессов, то nextin - мусор,
403: но это не имеет значения */
404: nextin = pipefds[0];
Единственный код, добавленный в ladsh2.с
для обеспечения перенаправлений — это функция setupRedirections()
, код которой останется неизменным во всех последующих версиях ladsh
. Ее задача состоит в обработке спецификаторов struct redirectionSpecifier
для дочерних заданий и соответствующей модификации дочерних файловых дескрипторов. Мы рекомендуем просмотреть код этой функции в приложении Б.
Глава 12
Обработка сигналов
Сигналы — это простейшая форма межпроцессного взаимодействия в мире POSIX. Они позволят одному процессу быть прерванным асинхронным образом по инициативе другого процесса (или ядра) для того, чтобы обработать какое-то событие. Обработав сигнал, прерванный процесс может продолжить выполнение с точки прерывания. Сигналы используются для решения таких задач, как завершение процессов и сообщения демонам о необходимости перечитать конфигурационный файл.
Сигналы всегда были неотъемлемой частью Unix. Ядро использует их для извещения процессов о разнообразных событиях, включая перечисленные ниже.
• Уничтожение одного из дочерних процессов.
• Установка предупреждений устаревшим процессам.
• Изменение размеров окна терминала.
Эти сообщения имеют важное свойство: все они асинхронные. Процесс не имеет никакого контроля над тем, когда завершится один из его дочерних процессов — это может случиться в любой точке выполнения родительского процесса. Каждое из этих событий посылает сигнал процессу. При получении сигнала процесс может сделать одну из трех вещей.
• Проигнорировать сигнал.
• Позволить ядру запустить специальную часть процесса, прежде чем продолжить выполнение основной его части (это называется перехватом сигнала).
• Позволить ядру выполнить действие по умолчанию, которое зависит от конкретного полученного сигнала.
Концептуально это довольно просто. Однако история развития средств работы с сигналами видна, когда вы сравните различные интерфейсы сигналов, которые поддерживаются различными реализациями Unix. BSD, System V и System 3 поддерживают различные и несовместимые программные интерфейсы сигналов. POSIX определил стандарт, теперь поддерживаемый почти всеми версиями Unix (включая Linux), который был тогда расширен для обработки новой семантики сигнала (вроде формирования очереди сигналов) как части определения сигнала в режиме реального времени POSIX (POSIX Real Time Signal). В этой главе обсуждается исходное выполнение сигналов Unix перед объяснением основ программного интерфейса POSIX и их расширений Real Time Signal, поскольку появление многих возможностей POSIX API было мотивировано недостатками в более ранних реализациях системы сигналов.
12.1. Концепция сигналов
12.1.1. Жизненный цикл сигнала
Сигналы имеют четко определенный жизненный цикл: они создаются, сохраняются до тех пор, пока ядро не выполнит определенное действие на основе сигнала, а затем вызывают совершение этого действия. Создание сигнала называют по-разному: поднятие(raising), генерацияили посылкасигнала. Обычно процесс посылает сигнал другому процессу, в то время как ядро генерирует сигналы для отправки процессу. Когда процесс посылает сигнал самому себе, говорят, что он поднимает его. Однако эти термины используются не особо согласованно.
Между временем, когда сигнал отправлен и тем, когда он вызывает какое-то действие, его называют ожидающим(pending). Это значит, что ядро знает, что сигнал должен быть обработан, но пока не имеет возможности сделать это. Как только сигнал поступает в процесс назначения, он называется доставленным. Если доставленный сигнал вызывает выполнение специального фрагмента кода (имеется в виду обработчик сигнала), то такой сигнал считается перехваченным. Есть разные способы, которыми процесс может предотвратить асинхронную доставку сигнала, но все же обработать его (например, с помощью системного вызова sigwait()
). Когда такое случается, сигнал называют принятым.
Чтобы облегчить понимание, мы будем использовать эту терминологию на протяжении всей книги [52] Эта терминология распространена в большей части литературы по стандартам, включая единую спецификацию Unix (Single Unix Specification).
.
12.1.2. Простые сигналы
Изначально обработка сигналов была проста. Системный вызов signal()
использовался для того, чтобы сообщить ядру, как доставить процессу определенный сигнал.
#include
void * signal(int signum, void *handler);
Здесь signum
— это сигнал, который нужно обработать, a handler
определяет действия, которое должно быть выполнено при доставке сигнала. Обычно handler
— это указатель на функцию-обработчик сигнала, которая не принимает параметров и не возвращает значения. Когда сигнал доставлен процессу, ядро как можно скорее запускает функцию-обработчик. Когда функция возвращает управление, ядро возобновляет выполнение процесса с того места, где он был прерван. Системные инженеры распознают в этом механизме обработки сигналов аналог доставки аппаратных прерываний. Прерывания и сигналы очень похожи и у них возникают сходные проблемы.
Интервал:
Закладка: