Мониторинг дочерних процессов
Как мы видели, всякий раз, когда мы создаем дочерний процесс из программы с помощью fork, происходит следующее:
- Текущий процесс теперь становится родительским.
- Новый процесс становится дочерним процессом
Что произойдет, если родительский процесс завершит свою задачу раньше, чем дочерний процесс, а затем завершится или завершится? Кто теперь будет родителем дочернего процесса? Родителем дочернего процесса является процесс init, который является самым первым процессом, запускающим все задачи.
Чтобы отслеживать состояние выполнения дочернего процесса, проверять, запущен или остановлен дочерний процесс, проверять состояние выполнения и т. Д., Используются системные вызовы wait () и их варианты.
Давайте рассмотрим пример программы, в которой родительский процесс не ждет дочернего процесса, в результате чего процесс init становится новым родительским процессом для дочернего процесса.
Имя файла: parentprocess_nowait.c
#include<stdio.h>
int main() {
int pid;
pid = fork();
// Child process
if (pid == 0) {
system("ps -ef");
sleep(10);
system("ps -ef");
} else {
sleep(3);
}
return 0;
}
Этапы компиляции и выполнения
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jan20 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql 101 1 0 Jan20 ? 00:04:41 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mariadb/mariadb.log --pid-file=/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock
3108506 5445 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 5446 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 21894 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 21895 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 27309 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
3108506 27311 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
8295652 32407 0 0 Jan20 ? 00:00:39 /sbin/klogd -c 1 -x -x
4688328 49830 0 0 Jan20 ? 00:00:18 /sbin/klogd -c 1 -x -x
3108506 50854 0 0 Jan20 ? 00:00:18 /sbin/klogd -c 1 -x -x
4688328 64936 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
3108506 64937 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
4688328 67563 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
5942779 68128 0 0 Jan22 ? 00:00:07 /sbin/klogd -c 1 -x -x
3108506 68238 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
4688328 68999 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
3108506 69212 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 74090 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
3108506 74091 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
4688328 74298 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 74299 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
6327201 74901 0 0 Jan20 ? 00:00:38 /sbin/klogd -c 1 -x -x
6327201 77274 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
7528790 78621 0 0 Jan20 ? 00:00:33 /sbin/klogd -c 1 -x -x
7528790 80536 0 0 Jan20 ? 00:01:09 [/sbin/klogd -c ] <defunct>
6327201 80542 0 0 Jan20 ? 00:01:09 [/sbin/klogd -c ] <defunct>
4688328 82050 0 0 Jan22 ? 00:01:59 [/sbin/klogd -c ] <defunct>
3108506 82051 0 0 Jan22 ? 00:01:59 [/sbin/klogd -c ] <defunct>
7528790 84116 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
7528790 84136 0 19 Jan20 ? 21:13:38 /sbin/klogd -c 1 -x -x
7528790 84140 0 0 Jan20 ? 00:00:28 /sbin/klogd -c 1 -x -x
3108506 84395 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
4688328 84396 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
5942779 84397 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
3108506 84928 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
4688328 84929 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
5942779 84930 0 0 Jan22 ? 00:00:30 [/sbin/klogd -c ] <defunct>
7528790 84970 0 0 Jan20 ? 00:00:34 /sbin/klogd -c 1 -x -x
3108506 85787 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 85789 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 86368 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 86402 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 87027 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
7528790 87629 0 0 Jan20 ? 00:00:39 /sbin/klogd -c 1 -x -x
7528790 87719 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
4688328 88138 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 88140 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 89353 0 99 Jan22 ? 2-07:35:14 /sbin/klogd -c 1 -x -x
5942779 91836 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
4688328 125358 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 125359 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 127456 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 127457 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
8023807 163891 0 0 05:41 ? 00:00:00 main
8023807 164130 0 0 05:41 ? 00:00:00 sh -c cd /home/cg/root/8023807; timeout 10s main
8023807 164136 164130 0 05:41 ? 00:00:00 timeout 10s main
8023807 164137 164136 0 05:41 ? 00:00:00 main
8023807 164138 164137 0 05:41 ? 00:00:00 main
8023807 164139 164138 0 05:41 ? 00:00:00 ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jan20 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql 101 1 0 Jan20 ? 00:04:41 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mariadb/mariadb.log --pid-file=/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock
3108506 5445 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 5446 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 21894 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 21895 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 27309 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
3108506 27311 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
8295652 32407 0 0 Jan20 ? 00:00:39 /sbin/klogd -c 1 -x -x
4688328 49830 0 0 Jan20 ? 00:00:18 /sbin/klogd -c 1 -x -x
3108506 50854 0 0 Jan20 ? 00:00:18 /sbin/klogd -c 1 -x -x
4688328 64936 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
3108506 64937 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
4688328 67563 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
5942779 68128 0 0 Jan22 ? 00:00:07 /sbin/klogd -c 1 -x -x
3108506 68238 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
4688328 68999 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
3108506 69212 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 74090 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
3108506 74091 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
4688328 74298 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 74299 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
6327201 74901 0 0 Jan20 ? 00:00:38 /sbin/klogd -c 1 -x -x
6327201 77274 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
7528790 78621 0 0 Jan20 ? 00:00:33 /sbin/klogd -c 1 -x -x
7528790 80536 0 0 Jan20 ? 00:01:09 [/sbin/klogd -c ] <defunct>
6327201 80542 0 0 Jan20 ? 00:01:09 [/sbin/klogd -c ] <defunct>
4688328 82050 0 0 Jan22 ? 00:01:59 [/sbin/klogd -c ] <defunct>
3108506 82051 0 0 Jan22 ? 00:01:59 [/sbin/klogd -c ] <defunct>
7528790 84116 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
7528790 84136 0 19 Jan20 ? 21:13:48 /sbin/klogd -c 1 -x -x
7528790 84140 0 0 Jan20 ? 00:00:28 /sbin/klogd -c 1 -x -x
3108506 84395 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
4688328 84396 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
5942779 84397 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
3108506 84928 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
4688328 84929 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
5942779 84930 0 0 Jan22 ? 00:00:30 [/sbin/klogd -c ] <defunct>
7528790 84970 0 0 Jan20 ? 00:00:34 /sbin/klogd -c 1 -x -x
3108506 85787 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 85789 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 86368 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 86402 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 87027 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
7528790 87629 0 0 Jan20 ? 00:00:39 /sbin/klogd -c 1 -x -x
7528790 87719 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
4688328 88138 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 88140 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 89353 0 99 Jan22 ? 2-07:35:24 /sbin/klogd -c 1 -x -x
5942779 91836 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
4688328 125358 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 125359 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 127456 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 127457 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
8023807 164138 0 0 05:41 ? 00:00:00 main
8023807 164897 164138 0 05:41 ? 00:00:00 ps -ef
Note - Обратите внимание, что PID родительского процесса был 94, а PID дочернего процесса был 95. После выхода из родительского процесса PPID дочернего процесса изменился с 94 на 1 (процесс инициализации).
Ниже приведены варианты системных вызовов для мониторинга дочерних процессов.
- wait()
- waitpid()
- waitid()
В wait() системный вызов будет ждать завершения одного из потомков и возвращать его статус завершения в буфере, как описано ниже.
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
Этот вызов возвращает идентификатор процесса прерванного дочернего процесса в случае успеха и -1 в случае неудачи. Системный вызов wait () приостанавливает выполнение текущего процесса и ожидает бесконечно, пока один из его дочерних процессов не завершится. Статус завершения от ребенка доступен в статусе.
Давайте изменим предыдущую программу так, чтобы родительский процесс теперь ждал дочерний процесс.
/ * Имя файла: parentprocess_waits.c * /
#include<stdio.h>
int main() {
int pid;
int status;
pid = fork();
// Child process
if (pid == 0) {
system("ps -ef");
sleep(10);
system("ps -ef");
return 3; //exit status is 3 from child process
} else {
sleep(3);
wait(&status);
printf("In parent process: exit status from child is decimal %d, hexa %0x\n", status, status);
}
return 0;
}
Этапы компиляции и выполнения
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jan20 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql 101 1 0 Jan20 ? 00:04:42 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mariadb/mariadb.log --pid-file=/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock
3108506 5445 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 5446 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 21894 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 21895 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 27309 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
3108506 27311 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
8295652 32407 0 0 Jan20 ? 00:00:39 /sbin/klogd -c 1 -x -x
4688328 49830 0 0 Jan20 ? 00:00:18 /sbin/klogd -c 1 -x -x
3108506 50854 0 0 Jan20 ? 00:00:18 /sbin/klogd -c 1 -x -x
4688328 64936 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
3108506 64937 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
4688328 67563 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
5942779 68128 0 0 Jan22 ? 00:00:07 /sbin/klogd -c 1 -x -x
3108506 68238 0 0 Jan22 ? 00:00:59 [/sbin/klogd -c ] <defunct>
4688328 68999 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
3108506 69212 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 74090 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
3108506 74091 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
4688328 74298 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 74299 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
6327201 74901 0 0 Jan20 ? 00:00:38 /sbin/klogd -c 1 -x -x
6327201 77274 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
7528790 78621 0 0 Jan20 ? 00:00:33 /sbin/klogd -c 1 -x -x
7528790 80536 0 0 Jan20 ? 00:01:09 [/sbin/klogd -c ] <defunct>
6327201 80542 0 0 Jan20 ? 00:01:09 [/sbin/klogd -c ] <defunct>
4688328 82050 0 0 Jan22 ? 00:01:59 [/sbin/klogd -c ] <defunct>
3108506 82051 0 0 Jan22 ? 00:01:59 [/sbin/klogd -c ] <defunct>
7528790 84116 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
7528790 84136 0 19 Jan20 ? 21:19:39 /sbin/klogd -c 1 -x -x
7528790 84140 0 0 Jan20 ? 00:00:28 /sbin/klogd -c 1 -x -x
3108506 84395 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
4688328 84396 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
5942779 84397 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
3108506 84928 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
4688328 84929 0 0 Jan22 ? 00:00:29 [/sbin/klogd -c ] <defunct>
5942779 84930 0 0 Jan22 ? 00:00:30 [/sbin/klogd -c ] <defunct>
7528790 84970 0 0 Jan20 ? 00:00:34 /sbin/klogd -c 1 -x -x
3108506 85787 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 85789 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 86368 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 86402 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 87027 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
7528790 87629 0 0 Jan20 ? 00:00:39 /sbin/klogd -c 1 -x -x
7528790 87719 0 0 Jan20 ? 00:00:27 /sbin/klogd -c 1 -x -x
4688328 88138 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
4688328 88140 0 0 Jan22 ? 00:00:14 [/sbin/klogd -c ] <defunct>
5942779 89353 0 99 Jan22 ? 2-07:41:15 /sbin/klogd -c 1 -x -x
5942779 91836 0 0 Jan22 ? 00:00:00 [/sbin/klogd -c ] <defunct>
4688328 125358 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 125359 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
4688328 127456 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
3108506 127457 0 0 Jan22 ? 00:01:19 [/sbin/klogd -c ] <defunct>
8023807 191762 0 0 05:47 ? 00:00:00 sh -c cd /home/cg/root/8023807; timeout 10s main
8023807 191768 191762 0 05:47 ? 00:00:00 timeout 10s main
8023807 191769 191768 0 05:47 ? 00:00:00 main
8023807 191770 191769 0 05:47 ? 00:00:00 main
8023807 192193 0 0 05:47 ? 00:00:00 sh -c cd /home/cg/root/8023807; timeout 10s main
8023807 192199 192193 0 05:47 ? 00:00:00 timeout 10s main
8023807 192200 192199 0 05:47 ? 00:00:00 main
8023807 192201 192200 0 05:47 ? 00:00:00 main
8023807 192202 192201 0 05:47 ? 00:00:00 ps -ef
Note- Несмотря на то, что дочерний процесс возвращает статус выхода 3, почему родительский процесс видит это как 768. Статус сохраняется в байте более высокого порядка, поэтому он сохраняется в шестнадцатеричном формате как 0X0300, что составляет 768 в десятичном формате. Нормальное завершение выглядит следующим образом
Байт высшего порядка (биты с 8 по 15) | Байт младшего разряда (биты с 0 по 7) |
Статус выхода (от 0 до 255) | 0 |
Системный вызов wait () имеет ограничение, например, он может ждать только до выхода следующего дочернего элемента. Если нам нужно дождаться определенного потомка, это невозможно с помощью wait (), однако это возможно с помощью системного вызова waitpid ().
Системный вызов waitpid () будет ждать завершения указанных дочерних элементов и возвращать статус завершения в буфере, как описано ниже.
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
Вышеупомянутый вызов возвращает идентификатор процесса завершенного дочернего процесса в случае успеха и -1 в случае неудачи. Системный вызов waitpid () приостанавливает выполнение текущего процесса и ожидает бесконечно, пока не завершатся указанные дочерние элементы (согласно значению pid). Статус завершения от ребенка доступен в статусе.
Значение pid может быть одним из следующих:
< -1 - Дождитесь появления любого дочернего процесса, идентификатор группы процессов которого равен абсолютному значению pid.
-1 - Дождитесь любого дочернего процесса, который соответствует системному вызову wait ().
0 - Дождитесь появления любого дочернего процесса, идентификатор группы процессов которого совпадает с идентификатором вызывающего процесса.
>0 - Дождитесь появления любого дочернего процесса, идентификатор процесса которого равен значению pid.
По умолчанию системный вызов waitpid () ожидает только завершенных дочерних элементов, но это поведение по умолчанию можно изменить с помощью аргумента options.
Теперь давайте рассмотрим программу в качестве примера, ожидающую определенного процесса с его идентификатором процесса.
/ * Имя файла: waitpid_test.c * /
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main() {
int pid;
int pids[3];
int status;
int numprocesses = 0;
int total_processes = 3;
while (numprocesses < total_processes) {
pid = fork();
// Child process
if (pid == 0) {
printf("In child process: process id is %d\n", getpid());
sleep(5);
return 4;
} else {
pids[numprocesses] = pid;
numprocesses++;
printf("In parent process: created process number: %d\n", pid);
}
}
// Waiting for 3rd child process
waitpid(pids[total_processes - 1], &status, 0);
if (WIFEXITED(status) != 0) {
printf("process %d exited normally\n", pids[total_processes - 1]);
printf("exit status from child is %d\n", WEXITSTATUS(status));
} else {
printf("process %d not exited normally\n", pids[total_processes - 1]);
}
return 0;
}
После компиляции и выполнения следующий результат.
In child process: process id is 32528
In parent process: created process number: 32528
In child process: process id is 32529
In parent process: created process number: 32528
In parent process: created process number: 32529
In child process: process id is 32530
In parent process: created process number: 32528
In parent process: created process number: 32529
In parent process: created process number: 32530
process 32530 exited normally
exit status from child is 4
Теперь давайте проверим системный вызов waitid (). Этот системный вызов ожидает изменения состояния дочерним процессом.
#include <sys/wait.h>
int waitpid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
Вышеупомянутый системный вызов ожидает, пока дочерний процесс изменит состояние, и этот вызов приостанавливает текущий / вызывающий процесс до тех пор, пока любой из его дочерних процессов не изменит свое состояние. Аргумент infop предназначен для записи текущего состояния дочернего элемента. Этот вызов немедленно возвращается, если процесс уже изменил свое состояние.
Значение idtype может быть одним из следующих:
P_PID - Дождитесь появления любого дочернего процесса, идентификатор процесса которого совпадает с идентификатором id.
P_PGID - Дождитесь появления любого дочернего процесса, идентификатор группы процессов которого совпадает с идентификатором id.
P_ALL - Дождитесь появления любого дочернего процесса, идентификатор игнорируется.
Аргумент options должен указать, какое состояние изменяется, и это может быть сформировано с помощью операции побитового ИЛИ с указанными ниже флагами:
WCONTINUED - Возвращает статус любого дочернего элемента, который был остановлен и был продолжен.
WEXITED - Ожидает завершения процесса.
WNOHANG - Возврат немедленно.
WSTOPPED - Ожидает завершения любого дочернего процесса при получении сигнала и возвращает статус.
Этот вызов возвращает 0, если он возвращается из-за изменения состояния одного из его дочерних элементов и используется WNOHANG. Он возвращает –1 в случае ошибки и устанавливает соответствующий номер ошибки.
/ * Имя файла: waitid_test.c * /
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main() {
int pid;
int pids[3];
int status;
int numprocesses = 0;
int total_processes = 3;
siginfo_t siginfo;
while (numprocesses < total_processes) {
pid = fork();
// Child process
if (pid == 0) {
printf("In child process: process id is %d\n", getpid());
sleep(5);
return 2;
} else {
pids[numprocesses] = pid;
numprocesses++;
printf("In parent process: created process number: %d\n", pid);
}
}
// Waiting for 3rd child process
status = waitid(P_PID, pids[total_processes - 1], &siginfo, WEXITED);
if (status == -1) {
perror("waitid error");
return 1;
}
printf("Info received from waitid is: ");
printf("PID of child: %d, real user id of child: %d\n", siginfo.si_pid, siginfo.si_uid);
return 0;
}
После выполнения и компиляции вышеуказанной программы результат будет следующим.
In child process: process id is 35390
In parent process: created process number: 35390
In child process: process id is 35391
In parent process: created process number: 35390
In parent process: created process number: 35391
In child process: process id is 35392
In parent process: created process number: 35390
In parent process: created process number: 35391
In parent process: created process number: 35392
Info received from waitid is: PID of child: 35392, real user id of child: 4581875