- Creating a Child Process with Redirected Input and Output
- Child Processes
- Создание асинхронных процессов
- Создание .bat и .cmd файлов в Windows
- child_process.exec(command[, options][, callback])
- child_process.execFile(file[, args][, options][, callback])
- child_process.fork(modulePath[, args][, options])
- child_process.spawn(command[, args][, options])
- options.detached
- options.stdio
- Создание синхронных процессов
- child_process.execFileSync(file[, args][, options])
- child_process.execSync(command[, options])
- child_process.spawnSync(command[, args][, options])
- Class: ChildProcess
- Event: ‘close’
- Event: ‘disconnect’
- Event: ‘error’
- Event: ‘exit’
- Event: ‘message’
- child.connected
- child.disconnect()
- child.kill([signal])
- child.pid
- child.send(message[, sendHandle[, options]][, callback])
- Пример: отправка объекта сервера
- Пример: отправка объекта сокета
- child.stderr
- child.stdin
- child.stdio
- child.stdout
- maxBuffer и Юникод
Creating a Child Process with Redirected Input and Output
The example in this topic demonstrates how to create a child process using the CreateProcess function from a console process. It also demonstrates a technique for using anonymous pipes to redirect the child process’s standard input and output handles. Note that named pipes can also be used to redirect process I/O.
The CreatePipe function uses the SECURITY_ATTRIBUTES structure to create inheritable handles to the read and write ends of two pipes. The read end of one pipe serves as standard input for the child process, and the write end of the other pipe is the standard output for the child process. These pipe handles are specified in the STARTUPINFO structure, which makes them the standard handles inherited by the child process.
The parent process uses the opposite ends of these two pipes to write to the child process’s input and read from the child process’s output. As specified in the SECURITY_ATTRIBUTES structure, these handles are also inheritable. However, these handles must not be inherited. Therefore, before creating the child process, the parent process uses the SetHandleInformation function to ensure that the write handle for the child process’s standard input and the read handle for the child process’s standard output cannot be inherited. For more information, see Pipes.
The following is the code for the parent process. It takes a single command-line argument: the name of a text file.
The following is the code for the child process. It uses the inherited handles for STDIN and STDOUT to access the pipe created by the parent. The parent process reads from its input file and writes the information to a pipe. The child receives text through the pipe using STDIN and writes to the pipe using STDOUT. The parent reads from the read end of the pipe and displays the information to its STDOUT.
Child Processes
Стабильность: 2 – Стабильно
Модуль child_process предоставляет возможность создавать дочерние процессы способом, похожим, но не идентичным popen(3). Эта возможность изначально поставлялась с функцией child_process.spawn() :
По умолчанию пути для stdin , stdout и stderr установлены между родительским процессом Node.js и порожденным дочерним процессом. Возможно передавать потоки данных по этим путям с отсутствующей блокировкой. Следует заметить, однако, что некоторые программы используют буферизацию строк ввода-вывода. Это никак не влияет на Node.js, но может означать то, что данные, передаваемые дочернему процессу, не будут приняты сразу.
Метод child_process.spawn() создает дочерние процессы асинхронным способом, без блокирования цикла обработки событий Node.js. Функция child_process.spawnSync() реализует эквивалентный функционал сихронным способом, который блокирует цикл обработки событий до тех пор, пока порожденные процессы не будут закончены закрыты.
Для удобства, модуль child_process предоставляет синхронные или асинхронные альтернативы child_process.spawn() и child_process.spawnSync() . Следует заметить, что каждая из этих альтернатив реализуется в начале child_process.spawn() или child_process.spawnSync()
- child_process.exec() : создает оболочку и запускает команду внутри этой оболочки, передавая stdout и stderr функции обратного вызова, если команда выполнена.
- child_process.execFile() : похоже на child_process.exec() , за исключением того, что эта функция запускает команду непосредственно, минуя создание оболочки.
- child_process.fork() : создает новый процесс Node.js и вызывает соответствующий модуль с предустановленным каналом связи IPC, который позволяет отправлять сообщения от родителя к дочернему процессу и в обратном порядке.
- child_process.execSync() : сихронизированная версия child_process.exec() , которая блокирует цикл обработки событий Node.js.
- child_process.execFileSync() : синхронизированная версия child_process.execFile() , которая блокирует цикл обработки событий Node.js.
Для определенных пользовательских случаев, таких, как автоматизированные скриптовые оболочки, синхронные аналоги могут быть удобнее. Во многих случаях, однако, синхронные методы могут иметь существенное влияние на производительность из-за приостанавливания цикла обработки событий, пока не выполнится дочерний процесс.
Создание асинхронных процессов
Методы child_process.spawn() , child_process.fork() , child_process.exec() и child_process.execFile() работают по асинхронному программному шаблону, характерному прочим Node.js API.
Каждый метод возвращает экземпляр ChildProcess . Эти объекты реализуют Node.js EventEmitter API, позволяя родительскому процессу регистрировать функции, которые вызываются тогда, когда имеют место определенные события в жизненном цикле дочернего процесса.
Методы child_process.exec() и child_process.execFile() также позволяют определить опциональную функцию обратного вызова callback , которая вызывается после завершения дочернего процесса.
Создание .bat и .cmd файлов в Windows
Актуальность применения child_process.exec() или child_process.execFile() во многом зависит от платформы. На Unix-системах (Unix, Linux, OSX) child_process.execFile() может быть более эффективной, так как эта функция не создает оболочку. На Windows .bat и .cmd файлы не выполняются сами без терминала, и, следовательно, не могут быть запущены с помощью code>child_process.execFile() . При запуске на Windows, .bat и .cmd файлы могут запускаться с помощью child_process.spawn() c оболочкой shell , посредством child_process.exec() , или созданием cmd.exe , которому передаются .bat и .cmd в качестве аргументов (то, что делает функция оболочки и child_process.exec() ).
child_process.exec(command[, options][, callback])
- command Команда запуска, аргументы разделяются пробелами
- options
- cwd Текущая рабочая директория дочернего процесса
- env Пара среды ключ-значение
- encoding (По умолчанию: ‘utf8’ )
- shell Оболочка для выполнения команды (По умолчанию: ‘/bin/sh’ ) на Unix, ‘cmd.exe’ на Windows. Оболочка должна понимать -c на Unix и /s /c на Windows. На Windows парсинг командной строки должен быть совместим с ‘cmd.exe’
- timeout (По умолчанию: 0 )
- maxBuffer Наибольшее количество данных (в байтах), дозволенное stdout или stderr, при превышении которого дочерний процесс будет завершен. (По умолчанию: 200\ *1024 )
- killSignal (По умолчанию: ‘SIGTERM’ )
- uid Устанавливает идентификатор пользователя процесса
- gid Устанавливает групповой идентификатор процесса
- callback Вызывается на выходе, когда процесс завершен
- error
- stdout |
- stderr ; |
- Return
Создает оболочку, после чего выполняет command в этой оболочке, буферизируя все сгенерированные выходы (output).
Если есть функция callback , она вызывается с аргументами error, stdout, stderr . В случае успешного запуска, error будет null . В случае наличия ошибки, error будет экземпляром Error . Свойство error.code будет кодом завершения дочернего процесса, пока error.signal установлено на оповещение при завершении процесса. Любой код выхода, отличный от 0 считается за ошибку.
Аргументы stdout и stderr , передаваемые функции обратного вызова, будут содержать выходы дочернего процесса stdout и stderr. По умолчанию, Node.js декодирует выходы в UTF-8 и передает строки функции обратного вызова. Параметр encoding может быть использован для определения кодировки символов, что применяется для декодирования выходов stdout и stderr. Если encoding передается ‘buffer’ , вместо строк функции обратного вызова будут передаваться объекты буфера.
Аргумент options может быть передан как второй аргумент, чтобы кастомизировать создание процесса. По умолчанию:
Если timeout больше 0 , родительский процесс будет отправлять сигнал, определенный свойством killSignal (по умолчанию ‘SIGTERM’ ), в случае, когда дочерний процесс запущен дольше, чем задано в timeout .
Примечание: в отличие от системного вызова POSIX exec(3) , child_process.exec() не заменяет существующий процесс и использует оболочку для выполнения команды.
child_process.execFile(file[, args][, options][, callback])
- file Имя выполняемого файла или путь к нему
- args Массив строчных аргументов
- options
- cwd Текущая рабочая директория дочернего процесса
- env Пара среды ключ-значение
- encoding (По умолчанию: ‘utf8’ )
- timeout (По умолчанию: 0 )
- maxBuffer Наибольшее количество данных (в байтах), дозволенное stdout или stderr, при превышении которого дочерний процесс будет завершен. (По умолчанию: 200\ *1024 )
- killSignal (По умолчанию: ‘SIGTERM’ )
- uid Устанавливает идентификатор пользователя процесса
- gid Устанавливает групповой идентификатор процесса
- callback Вызывается на выходе, когда процесс завершен
- error
- stdout | ;
- stderr |
- Return
Функция child_process.execFile () подобна child_process.exec () за исключением того, что она не растягивает оболочку. Скорее всего, указанный исполняемый файл вызывает новый процесс, что делает его немного более эффективным, чем child_process.exec () .
Поддерживаются такие же настройки, как и в child_process.exec() . В случае, если оболочка не создана, поведение, типа перенаправления входа-выхода и глобализации файлов не поддерживается.
Аргументы stdout и stderr , передаваемые функции обратного вызова содержат выходы stdout и stderr, относящиеся к дочернему процессу. По умолчанию, Node.js декодирует выходы в UTF-8 и передает функции обратного вызова строку. Опция encoding может использоваться для того, чтобы задать кодировку для декодирования выходов stdout и stderr. Если параметр encoding — это ‘buffer’ , то вместо строк фукнции обратного вызова будут переданы объекты буфера.
child_process.fork(modulePath[, args][, options])
- modulePath Модуль, запускаемый в дочернем процессе
- args Перечень аргументов строки
- options
- cwd Текущая рабочая директория дочернего процесса
- env Пары ключ-значение
- execPath Выполняемая функция для создания дочернего процесса
- execArgv Перечень аргументов строки, передаваемых выполняемой функции (по умолчанию: process.execArgv )
- silent Если значение true , то stdin, stdout и stderr дочернего процесса будут передаваться к родительскому процессе, в противном случае они будут наследоваться от родительского процесса. См. опции ‘pipe’ и ‘inherit’ из child_process.spawn() для более детальной информации. (По умолчанию: false )
- uid Устанавливает пользователя процесса
- gid Устанавливает группу пользователей процесса
- Return:
Метод child_process.fork() является частным случаем child_process.spawn() , который используется определенно для создания новых процессов Node.js. Подобно child_process.spawn() , в итоге возвращается объект ChildProcess. Возвращаемый ChildProcess имеет дополнительные каналы связи, которые позволяют сообщениям передаваться по обоим направлениям (вперед-назад) между родительским и дочерним процессом.
Важно иметь в виду, что созданные дочерние процессы в Node.js являются независимыми от родительских, за исключением канала связи IPC, который устанавливается между ними. Каждый процесс имеет собственную память, с собственными экземплярами V8. Из-за требований к дополнительному выделению ресурсов, не рекомендуется создание большого количества дочерних процессов.
По умолчанию, child_process.fork() создает новые экземпляры Node.js, используя process.execPath из родительского процесса. Свойство execPath в объекте позволяет использовать альтернативный путь выполнения.
Процессы Node.js, зпапускаемые с помощью кастомного execPath сообщаются с родительским процессом через файловый дескриптор (fd), который определяется переменной окружения NODE_CHANELL_FD в дочернем процессе. Входом и выходом в этом дескрипторе являются объекты JSON, разделенные строкой.
Примечание: В отличие от fork(2) POSIX системного вызова, child_process.fork() не клонирует текущий процесс.
child_process.spawn(command[, args][, options])
- command Команда запуска
- args Перечень аргументов строки
- options
- cwd Текущая рабочая директория дочернего процесса
- env Пары ключ-значение
- stdio | Конфигурация stdio дочернего процесса
- detached Подготавливает дочерний процесс к запуску независимо от родительского. Поведение определяется в зависимости от платформы (см. options.stdio )
- uid Устанавливает пользователя процесса (см. setuid(2) )
- gid Устанавливает группу пользователей процесса (см. setgid(2) )
- shell | При значении true , запускает command внутри оболочки. На UNIX: ‘/bin/sh’ , Windows: ‘cmd.exe’ . Любая другая оболочка может быть определена как строка. Оболочка должна понимать свитч -c на UNIX и /s /c на Windows. По умолчанию: false (без оболочки)
- Return:
Метод child_process.spawn() создает новый процесс, используя заданную command с аргументами командной строки args . Если это не указано, args по умолчанию содержит пустой массив.
Третий аргумент может использоваться для задания дополнительных опций и параметров с такими параметрами по умолчанию:
Используйте cwd для определения рабочей директории, в которой создается процесс. Если директория не задана, то по умолчанию наследуется текущая рабочая директория родительского процесса.
Используйте env , чтобы задать переменные окружения, которые будут доступны новому процессу. По умолчанию: process.env .
Пример запуска ls -lh /usr , с stdout , stderr и кодом выхода:
Пример: сложный способ запуска ps ax | grep ssh
Пример проверки на неудавшийся запуск:
options.detached
На Windows задание options.detached значения true делает возможным продолжение запуска дочернего процесса после того, как завершается родительский. Дочерний будет иметь собственное консольное окно. После запуска дочернего процесса, он не может быть прерван.
На других платформах, если options.detached задано значение true , дочерний процесс будет основным в группе новых процессов и сессий. Заметьте, что дочерний процесс может продолжать запуск после завершения родительского вне зависимости от того, разделены они или нет. Для более подробной информации см. setsid(2).
По умолчанию, родительский процесс должен ждать отделения от дочернего, чтобы завершиться. Чтобы предотвратить ожидание, следует использовать метод child.unref() . Выполнение этого метода исключит из родительского событийного цикла дочерний процесс, позволяя родителю завершиться отдельно от дочернего, несмотря на установленный между ними канал связи IPC.
При использовании опции detached для старта долговыполняемого процесса, процесс не будет запущен на фоне после завершения родительского, если только он не содержит stdio конфигурацию, которая не коннектится к родителю. Если же stdio наследуется от родителя, дочерний процесс останется прикрепленным к управляющему терминалу.
Пример долговыполняемого процесса с отделением и игнорированием файловых дескрипторов stdio родительского процесса:
Альтернативный способ: перенаправление выхода дочернего процесса в файлы:
options.stdio
Опция options.stdio предназначена для конфигурирования каналов, настроенных между родительскими и дочерними процессами. По умолчанию, дочерние stdin, stdout и stderr перенаправляются на соответствующие стримы child.stdin, child.stdout и child.stderr в объекте ChildProcess. Это равнозначно приравниванию options.stdio к [‘pipe’, ‘pipe’, ‘pipe’] .
Для удобства options.stdio может быть одной из нижеприведенных строк:
- ‘pipe’ – эквивалент [‘pipe’, ‘pipe’, ‘pipe’] (по умолчанию)
- ‘ignore’ – эквивалент [‘ignore’, ‘ignore’, ‘ignore’]
- ‘inherit’ – эквивалент [process.stdin, process.stdout, process.stderr] или [0,1,2]
В ином случае, значение options.stdio является массивом, где каждый индекс относится к файловому дескриптору дочернего процесса. Дескрипторы 0 , 1 , 2 ссылаются на stdin , stdout и stderr соответственно. Можно задать дополнительный дескриптор для создания дополнительных каналов между родителем и дочерним процессом. Значение будет одним из следующих:
- ‘pipe’ – создает канал между дочерним и родительским процессом. Конец канала со стороны рродителя является свойством объекта child_process как child.stdio[fd]. Каналы устанавливаются под дескрипторами 0–2 и могут ссылаться на child.stdin, child.stdout и child.stderr соответственно.
- ‘ipc’ – создает канал IPC для передачи сообщений/файловых дескрипторов от родителя к дочернему процессу и в обратном порядке. ChildProcess может иметь не более одного IPC stdio файлового дескриптора. Установка этой опции делает возможным выполнение метода child.send() . Если дочерний процесс записывает JSON сообщение в файловый дескриптор, обработчик события child.on(‘message’) будет запущен и в родительском процессе. Если дочерний является процессом Node.js, то наличие IPC канала позволяет выполняться методам process.send() , process.disconnect() , process.on(‘disconnect’) , и process.on(‘message’) в дочернем процессе.
- ‘ignore’ – заставляет Node.js игнорировать файловый дескриптор в дочернем процессе. Так как Node.js всегда оставляет открытыми дескрипторы 0–2 для порожденных им же процессов, установка дескриптора на ‘ignore’ заставит Node.js открыть /dev/null и назначить как дескриптор дочернего процесса.
- объект – расшаривает открытый для чтения или записи стрим, который ссылается на tty, файл, сокет или канал с дочерним процессом. Основной дескриптор стрима дублируется в дочерний процесс как файловый дескриптор, который соотносится с индексом массива stdio . Следует заметить, что стрим должен иметь базовый (основной) дескриптор (файловые стримы не имеют его, пока не запущено событие ‘open’ )
- Положительное число – целое значение, которое интерпретируется как файловый дескриптор, на данный момент открытый родительскому процессу. Он расшаривается на дочерний процесс так же, как и объекты .
- null , undefined – используюь значение по умолчанию. Для дескрипторов stdio 0, 1 и 2 (иными словами, stdin, stdout и stderr) создается канал. Для дескрипторов от 3 и больше по умолчанию задается ‘ignore’
Следует заметить, что, когда устанавливается канал IPC между родительским и дочерним процессом, и дочерний процесс является процессом Node.js, дочерний запускается с быссылочным IPC каналом ( unref() ), пока регистрируется обработчик событий для события process.on(‘disconnect’) . Это позволяет дочернему процессу нормально завершиться без привязки к открытому IPC каналу.
Создание синхронных процессов
Методы child_process.spawnSync() , child_process.execSync() и child_process.execFileSync() являются синхронными и будут блокировать цикл событий Node.js, приостанавливая выполнение любого добавочного кода, пока завершается созданный процесс.
Блокировка вызовов по такому типу используется в основном для упрощения общецелевых скриптовых задач, а также для упрощения загрузки/обработки конфигурации приложения при запуске.
child_process.execFileSync(file[, args][, options])
- file Имя пути, по которому находится выполняемый файл для запуска
- args Перечень аргументов строки
- options
- cwd Текущая рабочая директория дочернего процесса
- input ; | Значение, которое будет передаваться как stdin созданному процессу (это значение будет перезаписывать stdio[0] )
- stdio Конфигурация stdio дочернего процесса. По умолчанию: ‘pipe’
- stderr по умолчанию является выходом stderr родительского процесса, если не задано stdio
- env Пара среды ключ-значение
- uid Устанавливает идентификатор пользователя процесса
- gid Устанавливает групповой идентификатор процесса
- encoding (По умолчанию: ‘utf8’ )
- timeout (По умолчанию: undefined )
- maxBuffer Наибольшее количество данных (в байтах), дозволенное stdout или stderr, при превышении которого дочерний процесс будет завершен.
- killSignal (По умолчанию: ‘SIGTERM’ )
- encoding (По умолчанию: ‘utf8’ )
Метод child_process.execFileSync() в общем идентичен child_process.execFile(), за исключением того, что этот метод не возвращает значение, пока процесс полностью не закроется. Когда выйдет время timeout и будет отправлен killSignal , метод не возвращает ничего, пока процее полностью не будет завершен. Заметьте, что если дочерний процесс перехватывает сигнал SIGTERM , и при этом не завершается, родительский процесс будет приостановлен до тех пор, пока не завершится дочерний процесс.
Если вышло время выполнения процесса, или он имеет непустой код выхода, этот метод будет выдавать ошибку. Объект Error будет содержать весь результат из child_process.spawnSync()
child_process.execSync(command[, options])
- file ; Имя пути, по которому находится выполняемый файл для запуска
- args Перечень аргументов строки
- options
- cwd Текущая рабочая директория дочернего процесса
- input | Значение, которое будет передаваться как stdin созданному процессу (это значение будет перезаписывать stdio[0] )
- stdio Конфигурация stdio дочернего процесса. По умолчанию: ‘pipe’
- stderr по умолчанию является выходом stderr родительского процесса, если не задано stdio
- env Пара среды ключ-значение
- shell ; Оболочка для выполнения команды. По умолчанию: на UNIX: ‘/bin/sh’ , Windows: ‘cmd.exe’ . Любая другая оболочка может быть определена как строка. Оболочка должна понимать свитч -c на UNIX и /s /c на Windows. На Windows парсинг командной строки должен быть совместим с cmd.exe
- uid Устанавливает идентификатор пользователя процесса
- gid Устанавливает групповой идентификатор процесса
- encoding (По умолчанию: ‘utf8’ )
- timeout (По умолчанию: undefined )
- maxBuffer Наибольшее количество данных (в байтах), дозволенное stdout или stderr, при превышении которого дочерний процесс будет завершен.
- killSignal (По умолчанию: ‘SIGTERM’ )
- encoding ; (По умолчанию: ‘utf8’ )
Метод child_process.execSync() в общем идентичен child_process.exec() , за исключением того, что этот метод не возвращает значение, пока процесс полностью не закроется. Когда выйдет время timeout и будет отправлен killSignal , метод не возвращает ничего, пока процесс полностью не будет завершен. Заметьте, что если дочерний процесс перехватывает сигнал SIGTERM , и при этом не завершается, родительский процесс будет приостановлен до тех пор, пока не завершится дочерний процесс.
Если вышло время выполнения процесса, или он имеет непустой код выхода, этот метод будет выдавать ошибку. Объект Error будет содержать весь результат из child_process.spawnSync()
child_process.spawnSync(command[, args][, options])
- file Имя пути, по которому находится выполняемый файл для запуска
- args Перечень аргументов строки
- options
- cwd Текущая рабочая директория дочернего процесса
- input | Значение, которое будет передаваться как stdin созданному процессу (это значение будет перезаписывать stdio[0] )
- stdio Конфигурация stdio дочернего процесса. По умолчанию: ‘pipe’
- stderr по умолчанию является выходом stderr родительского процесса, если не задано stdio
- env Пара среды ключ-значение
- uid Устанавливает идентификатор пользователя процесса
- gid Устанавливает групповой идентификатор процесса
- encoding (По умолчанию: ‘utf8’ )
- timeout ; В миллисекундах — максимальное время, в пределах которого может быть запущен процесс (По умолчанию: undefined )
- maxBuffer Наибольшее количество данных (в байтах), дозволенное stdout или stderr, при превышении которого дочерний процесс будет завершен.
- killSignal (По умолчанию: ‘SIGTERM’ )
- encoding ; (По умолчанию: ‘utf8’ )
- shell | При значении true , запускает command внутри оболочки. На UNIX: ‘/bin/sh’ , Windows: ‘cmd.exe’ . Любая другая оболочка может быть определена как строка. Оболочка должна понимать свитч -c на UNIX и /s /c на Windows. По умолчанию: false (без оболочки)
- Return | stdout из command
- pid Pid дочернего процесса
- output Массив результатов из выхода stdio
- stdout | Содержимое output[1]
- stderr | Содержимое output[2]
- status Код выхода дочернего процесса
- signal Сигнал для прерывания дочернего процесса
- error ; Ошибка, выдаваемая в случае, когда дочерний процесс неудачно запущен или время выполнения вышло
Метод child_process.spawnSync() в общем идентичен child_process.spawn() , за исключением того, что этот метод не возвращает значение, пока процесс полностью не закроется. Когда выйдет время timeout и будет отправлен killSignal , метод не возвращает ничего, пока процесс полностью не будет завершен. Заметьте, что если дочерний процесс перехватывает сигнал SIGTERM , и при этом не завершается, родительский процесс будет приостановлен до тех пор, пока не завершится дочерний процесс.
Если вышло время выполнения процесса, или он имеет непустой код выхода, этот метод будет выдавать ошибку. Объект Error будет содержать весь результат из child_process.spawnSync()
Class: ChildProcess
Экземплярами класса ChildProcess являются ивент-эмиттеры (EventEmitters), которые относятся к созданному дочернему процессу.
Экземпляры ChildProcess не должны создаваться напрямую. Скорее, нужно использовать методы child_process.spawn(), child_process.exec(), child_process.execFile(), или child_process.fork() для их создания.
Event: ‘close’
- code Код выхода дочернего процесса, если процесс завершился самостоятельно
- signal Сигнал для завершения дочернего процесса
Событие ‘close’ запускается, когда потоки stdio дочернего процесса были закрыты. Это событие отличается от ‘exit’ , так как множественные процессы могут разделять одни и те же stdio потоки.
Event: ‘disconnect’
Событие ‘disconnect’ запускается после вызова метода child.disconnect() в родительском процессе или process.disconnect() в дочернем. После разъединения больше невозможно отправлять или получать сообщения , а также свойство child.connected будет false
Event: ‘error’
‘error’ может быть запущено когда угодно:
- Когда процесс не может быть создан, или
- Когда процесс не может быть «убит», или
- Не удалась отправка сообщения дочернему процессу.
Следует заметить, что событие ‘exit’ может или не может произойти после того, как выпала ошибка. Если вы ожидаете оба события, важно быть начеку по отношению к случайному многоразовому вызову функции обработчика.
См. тажже child.kill() и child.send() .
Event: ‘exit’
- code Код выхода дочернего процесса, если процесс завершился самостоятельно
- signal Сигнал для завершения дочернего процесса
Событие ‘exit’ вызывается после завершения дочернего процесса. Если процесс окончен, конечным кодом выхода процесса является code , во всех других случаях — null . Если процесс был прекращен по сигналу, названием строки сигнала будет signal , в противном случае — null . Какое-то одно из этих двух значений всегда будет не null .
Примечание: когда запускается событие ‘exit’ , потоки stdio дочернего процесса могут все еще быть открытыми.
Также, следует заметить, что Node.js устанавливает обработчики сигналов для SIGINT и SIGTERM и процессы Node.js не будут прекращены немедленно по этим сигналам. Скорее, Node.js выполнит последовательность действий по очистке и затем перезапустит обработанные сигналы.
Event: ‘message’
- message парсируемый JSON объект или примитивное значение
- sendHandle объект net.Socket или net.Server , также может быть незаданным
Событие ‘message’ запускается, когда дочерний процесс использует process.send() для отправки сообщений.
child.connected
- После вызова child.disconnect становится false
Свойство child.connected показывает, возможно ли еще отправлять и получать сообщения от дочернего процесса. Когда child.connected — false , это означает, что обмен сообщениями с дочерним процессом больше невозможен.
child.disconnect()
Закрывает IPC канал между родителем и дочерним процессом, позволяя дочернему процессу звершиться без препятствий при отсутствии работающих соединений. После вызова этого метода, свойства child.connected и process.connected в родительском и дочернем процессе соответственно будут установлены на false , и дальнейший обмен сообщениями между процессами больше не будет возможным.
Событие ‘disconnect’ запускается, когда нет получения сообщений. Чаще всего оно срабатывает сразу после вызова child.disconnect .
Следует заметить, что когда дочерний процесс является экземпляром Node.js (т.е. создан с помощью chuld_process.fork()), метод process.disconnect() может быть вызван в дочернем процессе, чтобы закрыть IPC канал.
child.kill([signal])
Методы child.kill() посылают сигнал дочернему процесс. Если аргументы не заданы, то процессу будет по умолчанию отправлен сигнал ‘SIGTERM’ . См. signal(7) для просмотра списка доступных сигналов.
Объект ChildProcess может вызывать событие ‘error’, если сигнал не может быть получен. Отправка сигнала дочернему процессу, который уже завершен, не рассматривается как ошибка, но может повлечь непредвиденные последствия. Конкретнее, если идентификатор процесса (PID) был переназначен на другой процесс, сигнал может быть получен этим процессом вместо заданного, что может иметь неожиданный результат.
Обратите внимание, что пока функция имеет имя kill , сигнал, передаваемый дочернему процессу, не может действительно прекратить процесс.
Также: на Linux дочерний процесс (или процессы) не могут быть прекращены, пока есть команда kill для их родительских процессов. Такое может случиться при запуске нового процесса в оболочке или с использованием опции shell в ChildProcess , как, например:
child.pid
Возвращает идентификатор дочернего процесса (PID).
child.send(message[, sendHandle[, options]][, callback])
- message
- sendhandle
- options
- callback
- Return:
Когда установлен IPC канал между родителем и дочерним процессом (при использовании child_process.fork()), можно использовать метод child.send() для отправки сообщений дочернему процессу. Если дочерний процесс является экземпляром Node.js, эти сообщения могут быть получены с помощью события process.on(‘message’) .
Скрипт для родителя в качестве примера:
И дочерний скрипт, sub.js , который может быть таким:
Дочерние процессы Node.js могут использовать метод process.send() или свой собственный, что позволяет дочернему процессу отправлять сообщения в обратном порядке, к родительскому процессу.
Особый случай — отправка сообщения
Опциональный аргумент sendHandle , который может быть передан child.send() , существует для
передачи TCP сервера или объекта сокета дочернему процессу. Дочерний процесс может получить объект как второй аргумент, переданный функции обратного вызова, что была зарегистрирована в событии process.on(‘message’). Любые полученные и отправленные в буфер данные сокета не будут отправляться дочернему процессу.
Аргумент options , если он существует, является объектом для параметризации отправки определенных типов обработчиков. options поддерживает следующие свойства:
- keepOpen – значение boolean , которое может использоваться при передаче экземпляров new.Socket . Если оно true , сокет остается открытым в процессе отправки. По умолчанию: false .
callback – это функция, которая вызывается после того, как сообщение было отправлено, но до того, как дочерний процесс его получит. Функция вызывается с одним единственным аргументом: null в случае удачного запуска и объектом Error в противном случае.
Если нет функции callback и сообщение не может быть отправлено, событие ‘error’ выпоняется объектом ChildProcess . Такое может произойти, например, когда дочерний процесс уже завершился.
child.send() будет возвращать false в случае, когда закрыт канал, а также если бэклог неотправленных сообщений превышает порог, выше которого нецелесообразна отправка сообщений в дальнейшем.В ином случае, метод возвращает true . Функцию callback можно использовать для реализации контроля потоков.
Пример: отправка объекта сервера
Аргумент sendHandle можно использовать, например, для передаче обработчика объекта TCP сервера дочернему процессу (как показано ниже):
Дочерний процесс будет получать этот объект сервера таким образом:
После того, как сервер расшарен между родителем и дочерним процессом, некоторые соединения могут быть обработаны родителем, а другие — дочерним.
В то время, как вышеприведенный пример иллюстрирует использование сервера, созданного с помощью модуля net , модуль dgram использует точно тот же рабочий процесс, за исключением просмотра события ‘message’ вместо ‘connection’ и использования server.bind() вместо server.listen() . Это, однако, на данный момент поддерживается только UNIX платформами.
Пример: отправка объекта сокета
Похожим образом аргумент sendHandler может быть использован для передачи обработчика сокета дочернему процессу. Пример ниже показывает создание двух «детей», каждый из которых обрабатывает соединения с приоритетами «normal» и «special»:
child.js будет получать обработчик сокета как второй аргумент, передаваемый событию функции обратного вызова:
После того, как сокет был передан дочернему процессу, родитель больше не имеет возможности отслеживать, где сокеты уничтожаются. Для определения этого, свойство .connections становится null . Рекомендуется не использовать .maxConnections , если попадается.
Примечание: эта функция использует внутри JSON.stringify() для сериализации сообщений.
child.stderr
Readable Stream (открытый для чтения стрим), что представляет stderr дочернего процесса.
Если дочерний процесс был создан с stdio[2] , установленным на что угодно, кроме ‘pipe’ , значит, значение по умолчанию будет undefined .
child.stderr является «союзником» child.stdio[2] . Оба свойства ссылаются на одно и то же значение.
child.stdin
Writable Stream (открытый для записи стрим), что представляет stdin дочернего процесса.
Важно: если дочерний процесс ожидает чтения всех своих входов, он не сможет продолжиться пока этот стрим не будет закрыт посредством end() .
Если дочерний процесс был создан с stdio[0] , установленным на что угодно, кроме ‘pipe’ , значит, значение по умолчанию будет undefined .
child.stdin является «союзником» child.stdio[0] . Оба свойства ссылаются на одно и то же значение.
child.stdio
«Разбросанный» массив каналов (pipes), ведущих к дочернему процессу, который ссылается на позиции опций stdio, переданных child_process.spawn(), которым было задано значение ‘pipe’ . Следует заметить, что child.stdio[0] , child.stdio[1] , и child.stdio[2] – то же самое, что и child.stdin , child.stdout , и child.stderr , соответственно.
В следующем примере демонстрируется, как только файловый дескриптор дочернего процесса 1 (stdout) конфигурируется как канал, так, что только родительский child.stdio[1] является стримом, все остальные значения в массиве null .
child.stdout
Readable Stream (открытый для чтения стрим), что представляет stdout дочернего процесса.
Если дочерний процесс был создан с stdio[1] , установленным на что угодно, кроме ‘pipe’ , значит, значение по умолчанию будет undefined .
child.stdout является «союзником» child.stdio[1] . Оба свойства ссылаются на одно и то же значение.
maxBuffer и Юникод
Важно помнить, что опция maxBuffer задает самое больше число октетов, допустимых в stdout и stderr . Если это значение превосходит заданное, дочерний процесс прерывается. Это практически влияет на выходы, которые включают в себя мультибайтовые кодировки символов, такие как UTF-8 или UTF-16. Например, следующий пример выводит 13 закодированных в UTF-8 октетов на stdout , хотя мы видим только 4 символа.