Опубликован: 06.12.2004 | Доступ: свободный | Студентов: 1179 / 142 | Оценка: 4.76 / 4.29 | Длительность: 20:58:00
ISBN: 978-5-9556-0021-5
Лекция 3:

Мобильное программирование приложений реального времени

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

При стандартизации средств одношагового порождения процессов преследовались две основные цели:

  • возможность использования на аппаратных конфигурациях без устройства управления памятью и без какого-либо специфического оборудования;
  • совместимость с существующими 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. Описание функций опроса и установки подразумеваемой обработки и маски сигналов в атрибутных объектах порождаемых процессов.