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

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

Жанры

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

Кёртен Роб

Шрифт:
P_WAIT Вызывающий процесс (ваша программа) будет блокирован до тех пор, пока вновь созданный процесс не отработает и не завершится.
P_NOWAIT Вызывающая программа не будет блокирована на время выполнения вновь созданной. Это позволяет вам запустить программу в фоновом режиме и продолжать выполнение, пока она делает свое дело.
P_NOWAITO Аналогично P_NOWAIT за исключением того, что устанавливается флаг SPAWN_NOZOMBIE. Это означает, что вы не должны беспокоить себя вызовом функции waitpid для очистки кода завершения
процесса.
P_OVERLAY Этот флаг превращает вызов функции spawn в соответствующей вызов exec! Ваша программа преобразуется в указанную программу без изменения идентификатора процесса ID. Вообще-то, если вы хотите сделать именно так, то, наверное, будет более корректно использовать вызов exec, поскольку это избавит будущих читателей ваших исходных текстов от необходимости искать P_OVERLAY в справочном руководстве по библиотеке языка Си!
Просто spawn

Как мы упомянули выше, все функции семейства spawn, в конечном счете, вызывают базовую функцию spawn. Ниже приведен прототип функции spawn:

#include <spawn.h>

pid_t spawn(const char *path, int fd_count,

 const int fd_map[], const struct inheritance *inherit,

 char* const argv[], char* const envp[]);

Мы можем не обращать внимание на параметры path, argv, и envp — мы уже рассмотрели их выше как местоположение исполняемого модуля (path), вектор параметров (argv) и окружение (envp).

Параметры fd_count и fd_map идут вместе. Если вы задаете нуль в fd_count, тогда fd_map игнорируется, и это означает, что вновь создаваемый процесс унаследует от родительского все дескрипторы файлов (кроме тех, которые модифицированы флагом FD_CLOEXEC функции fcntl). Если параметр fd_count имеет ненулевое значение, то он задает число дескрипторов файлов, содержащихся в fd_map, и будут унаследованы только они.

Параметр inherit — это указатель на структуру, которая содержит набор флагов, маски сигналов, и т.д. Для получения более подробной информации об этом вам следует обратиться за помощью к справочному руководству по библиотеке языка Си.

Запуск процесса при помощи функции fork

Предположим, что вы решили создать новый процесс, который был бы идентичен работающему в настоящее время процессу, и сделать это так, чтобы эти два процесса выполнялись одновременно. Вы могли бы решить эту проблему с помощью функции spawn (и параметра P_NOWAIT), передав вновь создаваемому процессу достаточно информации о точном состоянии вашего процесса, чтобы новый процесс мог настроить себя сам. Однако, такой подход может оказаться чрезвычайно сложным, потому что описание «текущего состояния» процесса может потребовать большого количества данных.

Существует более простой способ — применение функции fork которая просто копирует текущий процесс. У результирующего процесса как код, так и данные полностью совпадают с таковыми для родительского процесса.

Конечно же, невозможно создать процесс, который во всем был бы идентичен родительскому. Почему? Наиболее очевидное различие между этими двумя процессами должно быть в идентификаторе процесса — мы не можем создать два процесса с одним и тем же идентификатором. Если вы посмотрите документацию на функцию fork в справочном руководстве по библиотеке Си, вы увидите, что между этими двумя процессами будет иметь место ряд различий. Внимательно изучите этот список, чтоб быть уверенным в корректном применении функции fork.

Если после ветвления по fork получаются два одинаковых процесса, то как же их различить? Когда вы вызываете fork, вы тем самым создаете другой процесс, выполняющий тот же самый код и в том же самом местоположении (то есть оба процесса ввернутся из вызова fork), что и родительский. Рассмотрим пример программы:

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

 int retval;

 printf("Это определенно родительский процесс\n");

 fflush(stdout);

 retval = fork;

 printf("Кто это сказал?\n");

 return (EXIT_SUCCESS);

}

После вызова fork оба процесса выполнят второй вызов printf! Если вы запустите эту программу на выполнение, она выведет на экран примерно следующее:

Это определенно родительский процесс

Кто это сказал?

Кто это сказал?

Иными словами, оба процесса выведут вторую строку.

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

Китайская грамота, да? Проясним этот момент еще одним фрагментом программы:

printf("PID родителя равен %d\n", getpid);

fflush(stdout);

if (child_pid = fork) {

 printf("Это родитель, PID сына %d\n", child_pid);

} else {

 printf("Это сын, PID %d\n", getpid);

}

Эта программа выведет на экран примерно следующее:

PID родителя равен 4496

Это родитель, PID сына 8197

Это сын, PID 8197

Таким образом, после применения функции fork вы можете определить, в каком процессе находитесь («отец» это или «сын»), анализируя значение, возвращаемое функцией fork.

Запуск процесса с помощью функции vfork

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

Функция vfork создает «сына», но затем приостанавливает родительский поток до тех пор, пока «сын» не вызовет функцию exec или не завершится (с помощью exit или его друзей). В дополнение к этому, функция vfork будет работать в системах с физической моделью памяти, в то время как функция fork не сможет, потому что нуждается в создании такого же адресного пространства, а это в физической модели памяти просто невозможно.

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

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант

Измена. Осколки чувств

Верди Алиса
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Осколки чувств

Солдат Империи

Земляной Андрей Борисович
1. Страж
Фантастика:
попаданцы
альтернативная история
6.67
рейтинг книги
Солдат Империи

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

Моури Эрли
4. Ваше Сиятельство
Любовные романы:
эро литература
5.00
рейтинг книги
Ваше Сиятельство 4т

Идеальный мир для Социопата 3

Сапфир Олег
3. Социопат
Фантастика:
боевая фантастика
6.17
рейтинг книги
Идеальный мир для Социопата 3

Темный Патриарх Светлого Рода

Лисицин Евгений
1. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода

Рождение победителя

Каменистый Артем
3. Девятый
Фантастика:
фэнтези
альтернативная история
9.07
рейтинг книги
Рождение победителя

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

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

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Курсант: Назад в СССР 11

Дамиров Рафаэль
11. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: Назад в СССР 11

Замуж второй раз, или Ещё посмотрим, кто из нас попал!

Вудворт Франциска
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Замуж второй раз, или Ещё посмотрим, кто из нас попал!

Мне нужна жена

Юнина Наталья
Любовные романы:
современные любовные романы
6.88
рейтинг книги
Мне нужна жена

Темный Патриарх Светлого Рода 2

Лисицин Евгений
2. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 2

Большие дела

Ромов Дмитрий
7. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Большие дела