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

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

Жанры

Основы программирования в 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. Бедовый
Фантастика:
фэнтези
мистика
5.00
рейтинг книги
Царь царей

Легионы во Тьме 2

Владимиров Денис
10. Глэрд
Фантастика:
боевая фантастика
фэнтези
попаданцы
5.00
рейтинг книги
Легионы во Тьме 2

Хозяин Теней

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

Наследник

Шимохин Дмитрий
1. Старицкий
Приключения:
исторические приключения
5.00
рейтинг книги
Наследник

Наследник павшего дома. Том I

Вайс Александр
1. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том I

Великий род

Сай Ярослав
3. Медорфенов
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Великий род

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

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

Бояръ-Аниме. Газлайтер. Том 35

Володин Григорий Григорьевич
35. История Телепата
Фантастика:
аниме
боевая фантастика
фэнтези
5.00
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 35

Идеальный мир для Лекаря 26

Сапфир Олег
26. Лекарь
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 26

Я – Стрела. Трилогия

Суббота Светлана
Я - Стрела
Любовные романы:
любовно-фантастические романы
эро литература
6.82
рейтинг книги
Я – Стрела. Трилогия

Бальмануг. (Не) Любовница 2

Лашина Полина
4. Мир Десяти
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Бальмануг. (Не) Любовница 2

Позывной "Князь" 2

Котляров Лев
2. Князь Эгерман
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Позывной Князь 2

Последний Паладин. Том 13

Саваровский Роман
13. Путь Паладина
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 13

Наследник

Майерс Александр
3. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследник