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

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

Жанры

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

Создать новый процесс можно с помощью вызова

fork
. Системный вызов дублирует текущий процесс, создавая новый элемент в таблице процессов с множеством атрибутов, таких же как у текущего процесса. Новый процесс почти идентичен исходному, выполняет тот же программный код, но в своем пространстве данных, окружении и со своими файловыми дескрипторами. В комбинации с функциями
exec
вызов
fork
— все, что вам нужно для создания новых процессов.

#include <sys/types.h>

#include <unistd.h>

pid_t fork(void);

Как

видно из рис. 11.2, вызов
fork
возвращает в родительский процесс PID нового дочернего процесса. Новый процесс продолжает выполнение так же, как и исходный, за исключением того, что в дочерний процесс вызов
fork
возвращает 0. Это позволяет родительскому и дочернему процессам определить, "кто есть кто".

Рис. 11.2 

Если вызов

fork
завершается аварийно, он возвращает -1. Обычно это происходит из-за ограничения числа дочерних процессов, которые может иметь родительский процесс (
CHILD_MAX
), в этом случае переменной
errno
будет присвоено значение
EAGAIN
. Если для элемента таблицы процессов недостаточно места или не хватает виртуальной памяти, переменная
errno
получит значение
ENOMEM
.

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

fork
:

pid_t new_pid;

new_pid = fork;

switch(new_pid) {

case -1:

 /* Ошибка */

 break;

case 0:

 /* Мы — дочерний процесс */

 break;

default:

 /* Мы — родительский процесс */

 break;

}

Выполните упражнение 11.3.

Упражнение 11.3. Системный вызов
fork

Давайте рассмотрим простой пример fork1.с:

#include <sys/types.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

int main {

 pid_t pid;

 char* message;

 int n;

 printf("fork program starting\n");

 pid = fork;

 switch(pid) {

 case -1:

perror("fork failed");

exit(1);

 case 0:

message = "This is the child";

n = 5;

break;

 default:

message = "This is the parent";

n = 3;

break;

 }

 for (; n > 0; n--) {

puts(message);

sleep(1);

 }

 exit(0);

}

Эта

программа выполняет два процесса. Дочерний процесс создается и выводит пять раз сообщение. Исходный процесс (родитель) выводит сообщение только три раза. Родительский процесс завершается до того, как дочерний процесс выведет все свои сообщения, поэтому в вывод попадает очередное приглашение командной оболочки.

$ ./fork1

fork program starting

This is the child

This is the parent

This is the parent

This is the child

This is the parent

This is the child

$ This is the child

This is the child

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

Когда вызывается

fork
, эта программа делится на два отдельных процесса. Родительский процесс идентифицируется ненулевым возвращаемым из
fork
значением и используется для задания количества сообщений, выводимых с интервалом в одну секунду.

Ожидание процесса

Когда вы запускаете дочерний процесс с помощью вызова

fork
, он начинает жить собственной жизнью и выполняется независимо. Иногда вам нужно знать, когда закончился дочерний процесс. Например, в предыдущей программе родительский процесс завершается раньше дочернего, и вы получаете слегка беспорядочный вывод, потому что дочерний процесс продолжает выполняться. Вы можете с помощью системного вызова
wait
заставить родительский процесс дождаться завершения дочернего процесса перед своим продолжением.

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *stat_loc);

Системный вызов

wait
заставляет родительский процесс сделать паузу до тех пор, пока один из его дочерних процессов не остановится. Вызов возвращает PID дочернего процесса. Обычно это дочерний процесс, который завершился. Сведения о состоянии позволяют родительскому процессу определить статус завершения дочернего процесса, т.е. значение, возвращенное из функции
main
или переданное функции
exit
. Если
stat_loc
не равен пустому указателю, информация о состоянии будет записана в то место, на которое указывает этот параметр.

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

Запрети любить

Джейн Анна
1. Навсегда в моем сердце
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Запрети любить

Инженер Петра Великого 3

Гросов Виктор
3. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Инженер Петра Великого 3

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Рядовой. Назад в СССР. Книга 1

Гаусс Максим
1. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Рядовой. Назад в СССР. Книга 1

Газлайтер. Том 28

Володин Григорий Григорьевич
28. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 28

Спасите меня, Кацураги-сан! Том 3

Аржанов Алексей
3. Токийский лекарь
Фантастика:
городское фэнтези
попаданцы
дорама
фэнтези
5.00
рейтинг книги
Спасите меня, Кацураги-сан! Том 3

Последний реанорец. Том I и Том II

Павлов Вел
1. Высшая Речь
Фантастика:
фэнтези
7.62
рейтинг книги
Последний реанорец. Том I и Том II

Инженер Петра Великого 2

Гросов Виктор
2. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Инженер Петра Великого 2

Офицер империи

Земляной Андрей Борисович
2. Страж [Земляной]
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.50
рейтинг книги
Офицер империи

Первый среди равных. Книга VII

Бор Жорж
7. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Первый среди равных. Книга VII

Хозяин Стужи

Петров Максим Николаевич
1. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
7.00
рейтинг книги
Хозяин Стужи

На границе империй. Том 6

INDIGO
6. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.31
рейтинг книги
На границе империй. Том 6

Жена неверного ректора Полицейской академии

Удалова Юлия
Любовные романы:
любовно-фантастические романы
4.25
рейтинг книги
Жена неверного ректора Полицейской академии

Бастард

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