Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
108:
109: file = list;
110: prev = NULL;
111: while (file) {
112: if (!file->exists) {
113: printf("%s удален из %s\n", file->name, path);
114: free(file->name);
115:
116: if (!prev) {
117: /* удалить головной узел */
118: list = file->next;
119: free(file);
120: file = list;
121: } else {
122: prev->next = file->next;
123: free(file);
124: file = prev->next;
125: }
126: } else {
127: prev = file;
128: file = file->next;
129: }
130: }
131:
132: *listPtr = list;
133:
134: return 0;
135: }
136:
137: void handler(int sig, siginfo_t * siginfo, void * context) {
138: int i;
139:
140: for (i = 0; directoryList[i].path; i++) {
141: if (directoryList[i].fd == siginfo->si_fd) {
142: directoryList[i].changed = 1;
143: return;
144: }
145: }
146: }
147:
148: int main(int argc, char ** argv) {
149: struct sigaction act;
150: sigset_t mask, sigio;
151: int i;
152:
153: /* Блокировать SIGRTMIN. Мы не хотим получать его нигде,
154: кроме как внутри системного вызова sigsuspend(). */
155: sigemptyset(&sigio);
156: sigaddset(&sigio, SIGRTMIN);
157: sigprocmask(SIG_BLOCK, &sigio, &mask);
158:
159: act.sa_sigaction = handler;
160: act.sa_flags = SA_SIGINFO;
161: sigemptyset(&act.sa_mask);
162: sigaction(SIGRTMIN, &act, NULL);
163:
164: if (!argv[1]) {
165: /* ни одного аргумента не передано, привести argc/argv
166: к виду ".", как будто передается единственный аргумент */
167: argv[1] = ".";
168: argc++;
169: }
170:
171: /* каждый аргумент представляет собой отслеживаемый каталог */
172: directoryList = malloc(sizeof(*directoryList) * argc);
173: directoryList[argc - 1].path = NULL;
174:
175: for (i = 0; i < (argc - 1); i++) {
176: directoryList[i].path = argv[i + 1];
177: if ((directoryList[i].fd =
178: open(directoryList[i].path, O_RDONLY)) < 0) {
179: fprintf(stderr, "ошибка при открытии %s: %s\n",
180: directoryList[i].path, strerror(errno));
181: return 1;
182: }
183:
184: /* Отслеживание каталога перед первым сканированием;
185: это гарантирует, что мы захватим файлы, созданные кем-то
186: во время сканирования каталога. Если кто-то изменит его,
187: будет сгенерирован сигнал (и заблокирован, пока
188: мы не будем готовы принять его) */
189: if (fcntl(directoryList[i].fd, F_NOTIFY, DN_DELETE |
190: DN_CREATE | DN_RENAME | DN_MULTISHOT) ) {
191: perror("fcntl F_NOTIFY");
192: return 1;
193: }
194:
195: fcntl(directoryList[i].fd, F_SETSIG, SIGRTMIN);
196:
197: if (build DirectoryList(directoryList[i].path,
198: &directoryList[i].contents))
199: return 1;
200: }
201:
202: while (1) {
203: sigsuspend(&mask);
204:
205: for (i = 0; directoryList[i].path; i++)
206: if (directoryList[i].changed)
207: if (updateDirectoryList(directoryList[i].path,
208: &directoryList[i].contents))
209: return 1;
210: }
211:
212: return 0;
213: }
Глава 15
Управление заданиями
Управление заданиями — возможность, стандартизованная в POSIX.1 и предоставляемая многими другими стандартами — позволяет одному терминалу выполнять несколько заданий. Задание (job) — это один процесс или группа процессов, обычно соединенных каналами. Для перемещения заданий между передним планом и фоном и предотвращения доступа к терминалу фоновых заданий предусмотрены специальные механизмы.
15.1. Основы управления заданиями
Из главы 10 уже известно, что каждый активный терминал запускает группу процессов, которая называется сеансом. Каждый сеанс состоит из групп процессов, а каждая группа, в свою очередь, содержит один или несколько индивидуальных процессов.
Одна из групп процессов в сеансе является группой переднего плана. Остальные группы являются фоновыми. Фоновую группу можно заменить любой группой процессов, принадлежащей к сеансу, позволяя пользователю переключаться между группами процессов переднего плана. Процессы, являющиеся элементами группы процессов переднего плана, часто называют процессами переднего плана; остальные процессы называются фоновыми.
15.1.1. Перезапуск процессов
Каждый процесс может пребывать в трех состояниях: выполнение, останов и "зомби". Выполняющиеся процессы завершаются системным вызовом exit()
или отправкой сигнала фатального завершения. Процессы перемещаются между состояниями работы и остановки исключительно посредством сигналов, сгенерированных другим процессом, ядром либо ими самими [105] Остановленные процессы, однако, не могут генерировать сигналы, поэтому они также не могут перезапускаться.
.
Когда процесс получает SIGCONT
, ядро перемещает его из состояния останова в состояние выполнения; если процесс уже работает, сигнал не влияет на его состояние. Процесс может захватить сигнал; ядро в это время будет перемещать процесс в рабочее состояние перед передачей сигнала.
15.1.2. Остановка процессов
Четыре сигнала перемещают работающий процесс в состояние останова. SIGSTOP
никогда не генерируется ядром. Он предназначен для остановки произвольных процессов. Его невозможно захватить или проигнорировать; он всегда останавливает целевой процесс. Остальные три сигнала, останавливающие процессы — SIGTSTP
, SIGTTIN
и SIGTTOU
— могут генерироваться терминалом, на котором работает процесс, или другим процессом. Хотя эти сигналы ведут себя похожим образом, они генерируются при разных обстоятельствах.
SIGTSTP
Этот сигнал передается каждому процессу группы процессов переднего плана, когда пользователь нажимает клавиатурную комбинацию приостановки терминала [106] Обычно клавиатурной комбинацией приостановки является . Программа stty позволяет пользователям менять эту комбинацию. Подробнее это рассматривается в главе 16.
.
SIGTTIN
Когда фоновый процесс пытается считывать из терминала, ему передается SIGTTIN
.
SIGTTOU
Этот сигнал обычно генерируется фоновым процессом, пытающимся выполнить запись в свой терминал. Сигнал генерируется только в случае установки атрибута терминала TOSTOP
, как рассматривается в главе 16.
Данный сигнал генерируется также фоновым процессом, вызывающим tcflush()
, tcflow()
, tcsetattr()
, tcsetpgrp()
, tcdrain()
или tcsendbreak()
.
Действием по умолчанию каждого из этих трех сигналов является останов процесса. Все эти процессы можно поймать или игнорировать. В обоих случаях процесс не останавливается.
15.1.3. Обработка сигналов управления заданиями
Хотя многие приложения можно останавливать и перезапускать без побочных эффектов, другим процессам требуется обрабатывать состояния останова и запуска. Например, большинству редакторов необходимо модифицировать параметры терминала в рабочем состоянии. Когда пользователи приостанавливают процесс, они ожидают, что их терминал восстановит свое состояние по умолчанию.
Читать дальшеИнтервал:
Закладка: