Мобильное программирование приложений реального времени
Одношаговое порождение процессов
При стандартизации средств одношагового порождения процессов преследовались две основные цели:
- возможность использования на аппаратных конфигурациях без устройства управления памятью и без какого-либо специфического оборудования;
- совместимость с существующими POSIX-стандартами.
В качестве дополнительных целей объявлены:
- возможность эффективной реализации ;
- способность заменить двухшаговое порождение по крайней мере в половине типичных случаев;
- системы, где имеется только одношаговое порождение процессов, должны быть практически полезны, по крайней мере для приложений реального времени ;
- на системах с двухшаговым порождением процессов должна быть возможна библиотечная реализация одношагового порождения.
Еще одна дополнительная цель – простота интерфейса. Семейство exec*() насчитывает шесть членов; для posix_spawn*() хватило двух с единым списком аргументов в духе execve() и небольшими отличиями в трактовке имени файла с образом нового процесса (напоминающими разницу между execve() и execvp() ).
Более точно: для одношагового порождения процессов служат функции posix_spawn() и posix_spawnp() (см. листинг 3.1).
#include <spawn.h> int posix_spawn (pid_t *restrict pid, const char *restrict path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *restrict attrp, char *const argv [restrict], char *const envp [restrict]); int posix_spawnp (pid_t *restrict pid, const char *restrict file, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *restrict attrp, char *const argv [restrict], char *const envp [restrict]);Листинг 3.1. Описание функций одношагового порождения процессов.
Аргументами, отличающими posix_spawn() и posix_spawnp() от функций семейства exec*() являются pid, file_actions, attrp. Опишем их назначение.
По указателю pid (если он отличен от NULL ) возвращается идентификатор успешно порожденного процесса.
Аргументы file_actions и attrp отвечают за контроль сущностей, наследуемых при одношаговом порождении процессов. Чтобы достичь перечисленных выше целей, функции posix_spawn() и posix_spawnp() контролируют шесть видов наследуемых сущностей:
- файловые дескрипторы ;
- идентификатор группы процессов ;
- идентификаторы пользователя и группы процесса ;
- параметры планирования ;
- маску сигналов ;
- способ обработки сигналов, игнорируемых родительским процессом.
Контроль файловых дескрипторов, в первую очередь стандартных ввода, вывода и протокола, который осуществляется с помощью аргумента file_actions, позволяет порожденному процессу получить доступ к потокам данных, открытым или даже порожденным родительским процессом, без встраивания в исходный текст или передачи в качестве аргументов main() конкретных имен файлов или номеров дескрипторов.
Как правило, все открытые дескрипторы родительского процесса остаются таковыми и в порожденном, за исключением тех, у которых установлен флаг FD_CLOEXEC. Кроме того, если значение аргумента file_actions отлично от NULL, до обработки флагов FD_CLOEXEC принимается во внимание указуемый объект типа posix_spawn_file_actions_t, который содержит действия по закрытию, открытию и/или дублированию файловых дескрипторов. Для формирования объектов типа posix_spawn_file_actions_t служат функции posix_spawn_file_actions_init(), posix_spawn_file_actions_addclose(), posix_spawn_file_actions_addopen() и posix_spawn_file_actions_adddup2() ; функция posix_spawn_file_actions_destroy() ликвидирует подобный объект (см. листинг 3.2).
#include <spawn.h> int posix_spawn_file_actions_init (posix_spawn_file_actions_t *file_actions); int posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions); int posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions, int fildes); int posix_spawn_file_actions_addopen ( posix_spawn_file_actions_t *restrict file_actions, int fildes, const char *restrict path, int oflag, mode_t mode); int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions, int fildes, int newfildes);Листинг 3.2. Описание функций формирования и ликвидации объектов типа posix_spawn_file_actions_t.
Функция posix_spawn_file_actions_addclose() добавляет дескриптор fildes к числу закрываемых перед началом выполнения порожденного процесса. Функция posix_spawn_file_actions_addopen() предписывает открыть дескриптор fildes, как если бы был выполнен вызов open (path, oflag, mode). Наконец, функция posix_spawn_file_actions_adddup2() специфицирует дублирование дескриптора fildes в newfildes (close (newfildes); fcntl (fildes, F_DUPFD, newfildes)). Таким образом, функции posix_spawn() и posix_spawnp(), отправляясь от набора открытых дескрипторов родительского процесса, выполняют действия, заданные аргументом file_actions, и получают набор дескрипторов, открытых в порождаемом процессе, то есть родительский процесс берет на себя согласование по файловым дескрипторам с независимо созданным новым образом процесса.
Отметим, что с помощью функции posix_spawn_file_actions_addopen() удобно перенаправлять ввод/вывод порожденного процесса.
За контроль других сущностей, наследуемых при одношаговом порождении процессов, отвечает атрибутный объект, заданный аргументом attrp. Для формирования и опроса подобных объектов служат функции, показанные на листингах 3.3, 3.4 и 3.5.
#include <spawn.h> int posix_spawnattr_init ( posix_spawnattr_t *attr); int posix_spawnattr_destroy ( posix_spawnattr_t *attr); int posix_spawnattr_getflags ( const posix_spawnattr_t *restrict attr, short *restrict flags); int posix_spawnattr_setflags ( posix_spawnattr_t *attr, short flags); int posix_spawnattr_getpgroup ( const posix_spawnattr_t *restrict attr, pid_t *restrict pgroup); int posix_spawnattr_setpgroup ( posix_spawnattr_t *attr, pid_t pgroup);Листинг 3.3. Описание функций формирования и опроса атрибутных объектов порождаемых процессов.
#include <spawn.h> #include <sched.h> int posix_spawnattr_getschedparam ( const posix_spawnattr_t *restrict attr, struct sched_param *restrict schedparam); int posix_spawnattr_setschedparam ( posix_spawnattr_t *restrict attr, const struct sched_param *restrict schedparam); int posix_spawnattr_getschedpolicy ( const posix_spawnattr_t *restrict attr, int *restrict schedpolicy); int posix_spawnattr_setschedpolicy ( posix_spawnattr_t *attr, int schedpolicy);Листинг 3.4. Описание функций опроса и установки параметров и политики планирования в атрибутных объектах порождаемых процессов.
#include <spawn.h> #include <signal.h> int posix_spawnattr_getsigdefault ( const posix_spawnattr_t *restrict attr, sigset_t *restrict sigdefault); int posix_spawnattr_setsigdefault ( posix_spawnattr_t *restrict attr, const sigset_t *restrict sigdefault); int posix_spawnattr_getsigmask ( const posix_spawnattr_t *restrict attr, sigset_t *restrict sigmask); int posix_spawnattr_setsigmask ( posix_spawnattr_t *restrict attr, const sigset_t *restrict sigmask);Листинг 3.5. Описание функций опроса и установки подразумеваемой обработки и маски сигналов в атрибутных объектах порождаемых процессов.