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

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

Жанры

Основы программирования в Linux
Шрифт:

Как это работает

Если вы выполните только что приведенную программу с помощью команды

./fork2 &
и затем вызовите программу
ps
после завершения дочернего процесса, но до окончания родительского, то увидите строку, подобную следующей. (Некоторые системы могут сказать
<zombie>
вместо
<defunct>
.)

$ ps -аl

F S UID PID PPID С PRI NI ADDR SZ WCHAN TTY TIME CMD

004 S 0 1273 1259 0 75 0 - 589 wait4 pts/2 00:00:00 su

000 S 0 1274 1273 0 75 0 - 731 schedu pts/2 00:00:00 bash

000 S 500 1463 1262 0 75 0 - 788 schedu pts/1 00:00:00 oclock

000 S 500 1465 1262 0 75 0 - 2569 schedu pts/1 00:00:01 emacs

000 S 500 1603 1262 0 75 0 - 313 schedu pts/1 00:00:00 fork2

003 Z 500 1604 1603 0 75 0 - 0 do_exi pts/1 00:00:00 fork2 <defunct>

000 R 500 1605 1262 0 81 0 - 781 - pts/1 00:00:00 ps

Если

родительский процесс завершится необычно, дочерний процесс автоматически получит в качестве родителя процесс с PID, равным 1 (init). Теперь дочерний процесс — зомби, который уже не выполняется, но унаследован процессом
init
из-за необычного окончания родительского процесса. Зомби останется в таблице процессов, пока не пойман процессом
init
. Чем больше таблица, тем медленнее эта процедура. Следует избегать процессов-зомби, поскольку они потребляют ресурсы до тех пор, пока процесс init не вычистит их.

Есть еще один системный вызов, который можно применять для ожидания дочернего процесса. Он называется

waitpid
и применяется для ожидания завершения определенного процесса.

#include <sys/types.h>

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *stat_loc, int options);

Аргумент

pid
конкретный дочерний процесс, окончания которого нужно ждать. Если он равен –1,
waitpid
вернет информацию о любом дочернем процессе. Как и вызов
wait
, он записывает информацию о состоянии процесса в место, указанное аргументом
stat_loc
, если последний не равен пустому указателю. Аргумент
options
позволяет изменить поведение
waitpid
. Наиболее полезная опция
WNOHANG
мешает вызову
waitpid
приостанавливать выполнение вызвавшего его процесса. Ее можно применять для выяснения, завершился ли какой-либо из дочерних процессов, и если нет, то продолжать выполнение. Остальные опции такие же, как в вызове
wait
.

Итак, если вы хотите, чтобы родительский процесс периодически проверял, завершился ли конкретный дочерний процесс, можно использовать следующий вызов:

waitpid(child_pid, (int *)0, WNOHANG);

Он вернет ноль, если дочерний процесс не завершился и не остановлен, или

child_pid
, если это произошло. Вызов waitpid вернет -1 в случае ошибки и установит переменную
errno
. Это может произойти, если нет дочерних процессов (
errno
равна
ECHILD
),
если вызов прерван сигналом (
EINTR
) или аргумент
options
неверный (
EINVAL
).

Перенаправление ввода и вывода

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

fork
и
exec
. Следующий пример из упражнения 11.6 содержит программу-фильтр, которая читает из стандартного ввода и пишет в свой стандартный вывод, выполняя при этом некоторое полезное преобразование.

Далее приведена программа очень простой фильтрации upper.c, которая читает ввод и преобразует строчные буквы в прописные:

#include <stdio.h>

#include <ctype.h>

#include <stdlib.h>

int main {

 int ch;

 while ((ch = getchar) != EOF) {

putchar(toupper(ch));

 }

 exit(0);

}

Когда вы выполните программу, она сделает то, что и ожидалось:

$ ./upper

hello THERE

HELLO THERE

^D

$

Вы, конечно, можете применить ее для преобразования символов файла, используя перенаправление, применяемое командной оболочкой:

$ cat file.txt

this is the file, file.txt, it is all lower case.

$ ./upper < file.txt

THIS IS THE FILE, FILE.TXT, IT IS ALL LOWER CASE.

Что если вы хотите применить этот фильтр из другой программы? Программа useupper.c принимает имя файла как аргумент и откликается сообщением об ошибке при некорректном вызове:

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char *argv[]) {

 char *filename;

 if (argc != 2) {

fprintf (stderr, "usage: useupper file\n");

exit(1);

 }

 filename = argv[1];

Вы повторно открываете стандартный ввод, снова при этом проверяете наличие любых ошибок, а затем применяете функцию

execl
для вызова программы upper:

 if (!freopen(filename, "r", stdin)) {

fprintf(stderr, "could not redirect stdin from file %s\n", filename);

exit(2);

 }

 execl("./upper", "upper", 0);

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

Ваше Сиятельство 9

Моури Эрли
9. Ваше Сиятельство
Фантастика:
боевая фантастика
попаданцы
стимпанк
аниме
фэнтези
5.00
рейтинг книги
Ваше Сиятельство 9

Наследие Маозари 7

Панежин Евгений
7. Наследие Маозари
Фантастика:
боевая фантастика
юмористическое фэнтези
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 7

Гранит науки. Том 2

Зот Бакалавр
2. Героями не становятся, ими умирают
Фантастика:
фэнтези
5.00
рейтинг книги
Гранит науки. Том 2

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

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Меченный смертью. Том 4

Юрич Валерий
4. Меченный смертью
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Меченный смертью. Том 4

Ночной администратор

Ле Карре Джон
Детективы:
шпионские детективы
7.14
рейтинг книги
Ночной администратор

Господин Хладов

Шелег Дмитрий Витальевич
4. Кровь и лёд
Фантастика:
аниме
5.00
рейтинг книги
Господин Хладов

Адвокат Империи 12

Карелин Сергей Витальевич
12. Адвокат империи
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
попаданцы
5.00
рейтинг книги
Адвокат Империи 12

Петля, Кадетский корпус. Книга третья

Алексеев Евгений Артемович
3. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский корпус. Книга третья

Адвокат Империи 8

Карелин Сергей Витальевич
8. Адвокат империи
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
фантастика: прочее
попаданцы
5.00
рейтинг книги
Адвокат Империи 8

Локки 7. Потомок бога

Решетов Евгений Валерьевич
7. Локки
Фантастика:
аниме
эпическая фантастика
фэнтези
5.00
рейтинг книги
Локки 7. Потомок бога

Маг

Щепетнов Евгений Владимирович
2. Истринский цикл
Фантастика:
фэнтези
8.57
рейтинг книги
Маг

Весь цикл «Десантник на престоле». Шесть книг

Ланцов Михаил Алексеевич
Десантник на престоле
Фантастика:
альтернативная история
8.38
рейтинг книги
Весь цикл «Десантник на престоле». Шесть книг

"Новый Михаил-Империя Единства". Компиляцияя. Книги 1-17

Марков-Бабкин Владимир
Избранные циклы фантастических романов
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Новый Михаил-Империя Единства. Компиляцияя. Книги 1-17