QNX/UNIX: Анатомия параллелизма
Часть 10 из 16 Информация о книге
Ознакомительный фрагмент.
Большинство форм функции
являются POSIX-совместимыми, а большая часть форм функцииexec()представляет собой специфическое расширение QNX. Более того, даже для тех функций группыspawn(), которые часто называют POSIX-совместимыми [1], техническая документация QNX определяет степень совместимости примерно в таких терминах: « …функция spawn() является функцией QNX Neutrino (основанной на POSIX 1003.1d черновом стандарте).»spawn()Функции семейства
, напротив, подменяют исполняемый код текущего процесса (не изменяя его идентификатор PID, права доступа, внешние ресурсы процесса, а также находящийся в том же адресном пространстве) исполняемым кодом из другого файла. Поэтому используются эти вызовы непосредственно послеexec()для замены копии вызывающего процесса новым (это классическая UNIX-технология использования).fork()Функции семейства
, напротив, порождают новый процесс (с новым идентификатором PID и в новом адресном пространстве). Все формы вызовов spawn() после подготовительной работы (иногда очень значительной) в конечном итоге ретранслируются в вызов базовой формыspawn()[13], который последним действием своего выполнения и посылает сообщениеspawn()(менеджер процессов QNX, «территориально» объединенный с микроядром системы в одном файле).procntoБазовый вызов
определяется следующим образом: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
— размерность следующего за ним массиваfd_count;fd_map
— массив файловых дескрипторов, которые вы хотели бы унаследовать в дочернем процессе от родительского. Еслиfd_mapне равен 0 (то есть может иметь значения вплоть до константыfd_count), тоOPEN_MAXдолжен содержать список изfd_mapфайловых дескрипторов. Если жеfd_countравен 0, то дочерний процесс наследует все родительские дескрипторы, исключая те, которые созданы с флагомfd_countфункцииPD_CLOEXEC;fcntl()
— системная структура (см. системные определения) типаinherit, содержащая как минимум:struct inheritance
— один или более установленных бит:unsigned long flags
— позволитьSPAWN_CHECK_SCRIPTзапускать требуемый командный интерпретатор, интерпретируяspawn()как скрипт (интерпретатор указан в первой строке скриптаpath);path
— использовать переменную окруженияSPAWN_SEARCH_PATHдля поиска выполняемого файлаPATH;path
— установить для дочернего процесса значение группы, специфицируемое членом (структуры)SPAWN_SETGROUP. Если этот флаг не установлен, дочерний процесс будет частью текущей группы родительского процесса;pgroup
— запустить дочерний процесс на удаленном сетевом узле QNET, сам же удаленный узел специфицируется членом (структуры)SPAWN_SETND(см. команду удаленного запускаnd);on
— использовать структуруSPAWN_SETSIGDEFдля определения процесса множества (набора) сигналов, для которых будет установлена реакция по умолчанию. Если этот флаг не установлен, дочерний процесс наследует все сигнальные реакции родителя;sigdefault
— использоватьSPAWN_SETSIGMASKв качестве сигнальной маски дочернего процесса.sigmask
— группа дочернего процесса; имеет смысл, только если установлен флагpid_t pgroup. Если флагSPAWN_SETGROUPустановлен иSPAWN_SETGROUPустановлен какinherit.pgroup, то дочерний процесс открывает новую группу процессов с идентификатором группы (GID), равным PID этого нового процесса.SPAWN_NEWPGROUP
— сигнальная маска дочернего процесса, если установлен флагsigset_t sigmask.SPAWN_SETSIGMASK
— набор сигналов дочернего процесса, для которых определяется реакция по умолчанию, если установлен флагsigset_t sigdefault.SPAWN_SETSIGDEF
— это совершенно уникальный (относительно других ОС, а значит, и всего POSIX) параметр QNX - дескриптор узла сети QNET, на котором должен быть запущен новый процесс. Это поле используется, только если установлен флагuint32_t nd.SPAWN_SETND
— указатель массива аргументов. Значениеargvдолжно быть строкой (argv[0]), содержащей имя файла, загружаемого как процесс (но может бытьchar*, если аргументы не передаются). Последний элемент массиваNULLобязан бытьargv. Само значениеNULLникогда не может бытьargv.NULL
— указатель массива символьных строк переменных системного окружения (environment). Последний элемент массиваenvpобязан бытьenvp. Каждый элемент массива является строкой (NULL) вида: variable = value. Если само значение указателяchar*равноenvp, то дочерний процесс полностью наследует копию окружения родителя. (Окружение процесса — всегда «копия», поэтому любые изменения, внесенные в окружение дочерним процессом, никак не отражаются на окружении его родителя.)NULLПримечаниеЕсли дочерний процесс является скриптом интерпретатора (флаг
), то первая строка текста скрипта должна начинаться сSPAWN_CHECK_SCRIPT, за которыми должны следовать путь и аргументы того интерпретатора, который будет использоваться для интерпретации этого скрипта. К скрипту не применяется установленный в системе интерпретатор по умолчанию (как это происходит при вызове его по имени из командной строки).#!