Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

10.6.4. Висячие группы процессов

Механизм прерывания процессов (либо возобновления их работы после приостановки) при исчезновении их сеанса довольно сложен. Представьте себе сеанс со многими группами процессов в нем (см. рис. 10.1). Сеанс запущен на терминале, и обычная системная оболочка является его лидером.

Когда лидер сеанса (оболочка) завершается, ее группы процессов оказываются в сложной ситуации. Если они активно работают, то лишаются возможности использовать стандартные потоки

stdin
и
stdout
, поскольку терминал закрыт. Если они приостановлены, то вероятно, никогда не будут запущены снова, поскольку пользователь терминала не имеет возможности перезапустить их, к тому
же то, что они не могут быть запущены, означает также, что они не могут быть и прерваны.

В этой ситуации каждая такая группа процессов получает название висячей (orphaned). Стандарт POSIX определяет ее как группу процессов, чей родитель является также членом этой группы либо не является членом сеанса этой группы. Другими словами, группа процессов не является висячей до тех пор, пока у нее есть родительский процесс, принадлежащий тому же сеансу, но другой группе.

Хотя оба определения выглядят сложными, концепция достаточно проста. Если группа процессов приостановлена, и не существует процесса, который бы принудил ее возобновиться, то эта группа становится висячей [33] .

33

В главе 15 все это проясняется, поэтому, возможно, будет полезно сначала прочитать ее.

Когда завершает работу командная оболочка, все ее дочерние процессы становятся дочерними по отношению к процессу init, оставаясь при этом в своих исходных сеансах. Предполагая, что все программы в сеансе являются потомками оболочки, все группы процессов этого сеанса становятся висячими [34] . Когда группа процессов превращается в висячую, каждый процесс этой группы получает сигнал

SIGHUP
, что обычно прерывает программу.

Программы, которые не прерываются по сигналу

SIGHUP
, получают сигнал
SIGCONT
, который продолжает выполнение приостановленных процессов. Такая последовательность прерывает большинство процессов и обеспечивает оставшимся возможность работать (то есть гарантирует, что они не будет в приостановленном состоянии) [35] .

34

Но, может быть, не сразу. Может существовать группа процессов, содержащая процессы, чьи родители относятся к другой группе в том же сеансе. Поскольку отношения "родительский-дочерний" между процессами образуют дерево, иногда может оказаться, что существует группа процессов, которая содержит только те процессы, чьим родителем является оболочка, и когда такая группа процессов завершается, другая становится висячей.

35

Обсуждение станет более понятным после того, как вы прочитаете главы, посвященные сигналам (глава 12) и управлению заданиями (глава 15).

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

errno
в значение
EIO
. Процессы остаются в том же сеансе, и идентификатор сеанса не используется для новых идентификаторов процессов до тех пор, пока не завершатся все процессы данного сеанса.

10.7. Введение в

ladsh

Чтобы помочь проиллюстрировать идеи, обсуждаемые в нашей книге, на протяжении последующих разделов книги мы разработаем подмножество командной оболочки Unix. В конечном итоге наша оболочка будет поддерживать следующее.

• Простые встроенные команды.

• Запуск внешних команд.

• Перенаправление

ввода-вывода (
>
,
|
и так далее).

• Управление заданиями.

Полный исходный текст окончательной версии этой оболочки,

ladsh4.с
, представлен в приложении Б. По мере добавления в
ladsh
новых средств, изменения исходного текста описываются в тексте книги. Чтобы уменьшить количество изменений, которые мы вносим между версиями, некоторые ранние версии несколько более сложны, чем было бы нужно. Эти небольшие усложнения, однако, далее в книге упрощают разработку оболочки, поэтому будьте терпеливы. Просто пока поверьте, что эти фрагменты кода необходимы; все они будут объяснены позднее.

10.7.1. Запуск внешних программ с помощью ladsh

Вот первая (и самая простая) версия

ladsh
, называемая
ladsh1
.

1: /*ladsh1.c*/

2:

3: #include <ctype.h>

4: #include <errno.h>

5: #include <fcntl.h>

6: #include <signal.h>

7: #include <stdio.h>

8: #include <stdlib.h>

9: #include <string.h>

 10: #include <sys/ioctl.h>

 11: #include <sys/wait.h>

 12: #include <unistd.h>

 13:

 14: #define MAX_COMMAND_LEN 250 /* максимальная длина отдельной

 15: командной строки */

 16: #define JOB_STATUS_FORMAT "[%d]%-22s%.40s\n"

 17:

 18: struct jobSet {

 19: struct job *head; /* заголовок списка запущенных заданий */

 20: struct job *fg; /* текущее задание переднего плана */

 21: };

 22:

 23: struct childProgram {

 24: pid_t Pid; /* 0 на выходе */

 25: char **argv; /* имя программы с аргументами */

 26: };

 27:

 28: struct job {

 29: int job Id; /* номер задания */

 30: int numProgs; /* общее кол-во программ в задании */

 31: int runningProgs; /* кол-во работающих программ */

 32: char *text; /* имя задания */

 33: char *cmdBuf; /* буфер различных argv */

 34: pid_t pgrp; /* идентификатор группы процессов задания */

 35: struct childProgram *progs; /* массив программ в задании */

 36: struct job *next; /* для слежения за фоновыми программами */

 37: };

 38:

 39: void freeJob(struct job *cmd) {

 40: int i;

 41:

 42: for (i=0; i<cmd->numProgs; i++) {

 43: free (cmd->progs[i].argv);

 44: }

 45: free(cmd->progs);

 46: if (cmd->text) free(cmd->text);

 47: free(cmd->cmdBuf);

 48: }

Поделиться:
Популярные книги

Гарем вне закона 18+

Тесленок Кирилл Геннадьевич
1. Гарем вне закона
Фантастика:
фэнтези
юмористическая фантастика
6.73
рейтинг книги
Гарем вне закона 18+

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Санек

Седой Василий
1. Санек
Фантастика:
попаданцы
альтернативная история
4.00
рейтинг книги
Санек

Ярость Богов

Михайлов Дем Алексеевич
3. Мир Вальдиры
Фантастика:
фэнтези
рпг
9.48
рейтинг книги
Ярость Богов

Третье правило дворянина

Герда Александр
3. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Третье правило дворянина

Ученик. Книга третья

Первухин Андрей Евгеньевич
3. Ученик
Фантастика:
фэнтези
7.64
рейтинг книги
Ученик. Книга третья

Кодекс Охотника. Книга XV

Винокуров Юрий
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XV

Большая Гонка

Кораблев Родион
16. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Большая Гонка

Краш-тест для майора

Рам Янка
3. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
эро литература
6.25
рейтинг книги
Краш-тест для майора

Дикая фиалка Юга

Шах Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Дикая фиалка Юга

Идеальный мир для Социопата 4

Сапфир Олег
4. Социопат
Фантастика:
боевая фантастика
6.82
рейтинг книги
Идеальный мир для Социопата 4

Вперед в прошлое 6

Ратманов Денис
6. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 6

Специалист

Кораблев Родион
17. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Специалист

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке