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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

65 } else if (ret == 0) {

/* ...не изменившийся код пропущен... */

80 write(1, exited, strlen(exited));

81 }

Это идентично предыдущей версии за тем исключением, что у нас есть новая переменная,

kidsleft
, указывающая, сколько имеется не опрошенных потомков. Строки 15 и 64 помечают новый код.

83 /* main --- установка относящейся к порожденным процессам сведений

и сигналов, создание порожденных процессов */

84

85 int main(int argc, char **argv)

86 {

/* ...не изменившийся код пропущен... */

100

101 sigemptyset(&childset);

102 sigaddset(&childset, SIGCHLD);

103

104 /* sigprocmask(SIG_SETMASK, &childset, NULL); /* блокирование в коде main */

105

106 for (nkids = 0; nkids < 5; nkids++) {

107 if ((kids[nkids] = fork) == 0) {

108 sleep(3);

109 _exit(0);

110 }

111 kidsleft++; /* <<< Added */

112 }

113

114 /* sleep(5); /* дать потомкам шанс завершиться */

115

116 while (kidsleft > 0) { /* <<< Добавлено */

117 printf("waiting for signals\n");

118 sigsuspend(&emptyset);

119 } /* <<< Добавлено */

120

121 return 0;

122 }

Здесь код также почти идентичен. Строки 104 и 114 закомментированы из предыдущей версии, а строки 111, 116 и 119 добавлены. Удивительно, при запуске поведение меняется в зависимости от версии ядра!

$ uname -a /* Отобразить версию системы */

Linux example1 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux

$ ch10-reap2 /* Запустить программу */

waiting for signals

Entered childhandler /* Опрос одного потомка */

reaped process 2702

pid 2703 not available yet

pid 2704 not available yet

pid 2705 not available yet

pid 27 06 not available yet

Exited childhandler

waiting for signals

Entered childhandler /* И следующего */

reaped process 2703

pid 2704 not available yet

pid 2705 not available yet

pid 2706 not available yet

Exited childhandler

waiting for signals

Entered childhandler /* И так далее */

reaped process 2704

pid 2705 not available yet

pid 2706 not available yet

Exited childhandler

waiting for signals

Entered childhandler

reaped process 2705

pid 2706 not available yet

Exited childhandler

waiting for signals

Entered childhandler

reaped process 2706

Exited childhandler

В данном примере на каждый процесс поступает ровно один

SIGCHLD
! Хотя это прекрасно и полностью воспроизводимо на этой системе, это также необычно. Как на более раннем, так и на более позднем ядре и на Solaris программа получает один сигнал для более чем одного потомка:

$ uname -a /* Отобразить версию системы */

Linux example2 2.4.22-1.2115.npt1 #1 Wed Oct 29 15:42:51 EST 2003 i686 i686 i386 GNU/Linux

$ ch10-reap2 /* Запуск программы */

waiting for signals

Entered childhandler /* Обработчик сигнала вызван лишь однажды */

reaped process 9564

reaped process 9565

reaped process 9566

reaped process 9567

reaped process 9568

Exited childhandler

ЗАМЕЧАНИЕ. В коде для

ch10-reap2.c
есть один важный дефект — состояние гонки. Взгляните еще раз на строки 106–112 в
ch10-reap2.c
. Что случится, если
SIGCHLD
появится при исполнении этого кода? Массив
kids
и переменные
nkids
и
kidsleft
могут оказаться разрушенными: код в
main
добавляет новый процесс, но обработчик сигнала вычитает один.

Этот пример кода является отличным примером критического раздела; он не должен прерываться при исполнении. Правильным способом работы с этим кодом является заключение его между вызовами, которые сначала блокируют, а затем разблокируют

SIGCHLD
.

10.8.3.3. Строгий родительский контроль

Структура

siginfo_t
и перехватчик сигнала с тремя аргументами дают возможность узнать, что случилось с потомком. Для SIGCHLD поле
si_code
структуры
siginfo_t
указывает причину посылки сигнала (остановка, возобновление, завершение порожденного процесса и т.д.). В табл. 10.5 представлен полный список значений. Все они определены в качестве расширения XSI стандарта POSIX.

Следующая программа,

ch10-status.c
, демонстрирует использование структуры
siginfo_t
.

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

Тринадцатый XII

NikL
12. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
7.00
рейтинг книги
Тринадцатый XII

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Трапеция

Брэдли Мэрион Зиммер
Проза:
современная проза
5.00
рейтинг книги
Трапеция

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

Винокуров Юрий
34. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIV

Целеполагание

Владимиров Денис
4. Глэрд
Фантастика:
фэнтези
боевая фантастика
рпг
5.00
рейтинг книги
Целеполагание

Ким

Киплинг Редьярд Джозеф
Приключения:
исторические приключения
7.62
рейтинг книги
Ким

Последний Герой. Том 5

Дамиров Рафаэль
5. Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 5

Князь Андер Арес 2

Грехов Тимофей
2. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Князь Андер Арес 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Жут

Май Карл Фридрих
Приключения:
вестерны
6.25
рейтинг книги
Жут

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.35
рейтинг книги
Князь Мещерский

Некромант

Щепетнов Евгений Владимирович
4. Петр Синельников
Фантастика:
боевая фантастика
6.20
рейтинг книги
Некромант

Брак по-драконьи

Ардова Алиса
Фантастика:
фэнтези
8.60
рейтинг книги
Брак по-драконьи

Страж Кодекса. Книга VII

Романов Илья Николаевич
7. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга VII