Основы программирования в Linux
Основы программирования в Linux читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Вы сможете увидеть создание процесса-зомби, если измените количество сообщений в программе из примера с вызовом
fork
Программа fork2.c такая же, как программа fork1.с, за исключением того, что количества сообщений, выводимых родительским и дочерним процессами, поменяли местами. Далее приведены соответствующие строки кода:
switch (pid) {
case -1:
perror("fork failed");
exit(1);
case 0:
message = "This is the child";
<i> n = 3;</i>
break;
default:
message = "This is the parent";
<i> n = 5;</i>
break;
}
Как это работает
Если вы выполните только что приведенную программу с помощью команды
./fork2 &
ps
<zombie>
<defunct>
$ <b>ps -аl</b>
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
<i>003 Z 500 1604 1603 0 75 0 - 0 do_exi pts/1 00:00:00 fork2 <defunct></i>
000 R 500 1605 1262 0 81 0 - 781 - pts/1 00:00:00 ps
Если родительский процесс завершится необычно, дочерний процесс автоматически получит в качестве родителя процесс с PID, равным 1 (init). Теперь дочерний процесс — зомби, который уже не выполняется, но унаследован процессом
init
init
Есть еще один системный вызов, который можно применять для ожидания дочернего процесса. Он называется
waitpid
<b>#include <sys/types.h></b>
<b>#include <sys/wait.h></b>
<b>pid_t waitpid(pid_t pid, int *stat_loc, int options);</b>
Аргумент
pid
waitpid
wait
stat_loc
options
waitpid
WNOHANG
waitpid
wait
Итак, если вы хотите, чтобы родительский процесс периодически проверял, завершился ли конкретный дочерний процесс, можно использовать следующий вызов:
waitpid(child_pid, (int *)0, WNOHANG);
Он вернет ноль, если дочерний процесс не завершился и не остановлен, или
child_pid
errno
errno
ECHILD
EINTR
options
EINVAL
Перенаправление ввода и вывода
Вы можете применить ваши знания о процессах для изменения поведения программ, используя тот факт, что открытые файловые дескрипторы сохраняются вызовами
fork
exec
Далее приведена программа очень простой фильтрации upper.c, которая читает ввод и преобразует строчные буквы в прописные:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int main() {
int ch;
while ((ch = getchar()) != EOF) {
putchar(toupper(ch));
}
exit(0);
}
Когда вы выполните программу, она сделает то, что и ожидалось:
$ <b>./upper</b>
hello THERE
HELLO THERE
<b>^D</b>
$
Вы, конечно, можете применить ее для преобразования символов файла, используя перенаправление, применяемое командной оболочкой:
$ <b>cat file.txt</b>
this is the file, file.txt, it is all lower case.