Перейти к содержанию

Дочерние процессы

В Node.js дочерние процессы создаются для выполнения ресурсоемких операций, которые во время выполнения блокируют цикл событий основного процесса. Создаваемые дочерние процессы полностью независимы от родительского процесса и имеют свои собственные экземпляры V8 и выделенные мощности процессора и объем памяти.

Для создания дочернего процесса в Node.js используется встроенный модуль child_process и его методы spawn() и fork(), каждый из которых возвращает экземпляр класса ChildProcess.

child_process.spawn()

Метод child_process.spawn() создает новый дочерний процесс (не обязательно Node.js) командой, переданной ему в качестве параметра. Вторым параметром можно передать массив аргументов команды.

app.js

const child_process = require('child_process')

//Переход в директорию /srv/app
const cd = child_process.spawn('cd'['/srv/app'])

cd.on('error', error => console.log('Cannot change dir: \n', error))

//Получение списка файлов и директорий для Linux
const ls = child_process.spawn('ls')

ls.stdout.on('data', data => console.log('Files list: \n', data))
ls.stderr.on('error', error => console.log('Error: \n', error))

Практически всегда в качестве дополнительного процесса вам придется запускать модуль Node.js. Для этого вместо метода child_process.spawn() используйте child_process.fork().

child_process.fork()

Метод child_process.fork() является частным случаем метода child_process.spawn(), только вместо команды он принимает путь к модулю, который должен быть запущен как новый процесс. Вторым параметром передается массив аргументом для запуска модуля.

app.js

const child_process = require('child_process')

const child_3 = child_process.fork('child.js', [3])
const child_9 = child_process.fork('child.js', [9])

child_3.on('close', code => console.log(`Child process 3 exited. Code: ${code}`))
child_9.on('close', code => console.log(`Child process 9 exited. Code: ${code}`))

child.js

console.log(`Child process ${process.argv[2]} is running`)

Для запуска примера выполните команду.

node app.js

В результате в консоли вы должны увидеть следующее.

Child process 3 is running
Child process 9 is running
Child process 3 exited. Code: 0
Child process 9 exited. Code: 0

Для взаимодействия основного и дочернего процессов используется метод send(), который устанавливает между процессами IPC канал для обмена сообщениями и параметром принимает данные для отправки другому процессу. Переданные данные являются аргументами для callback-функции, определяемой для обработки сообщения.

app.js

const child_process = require('child_process')

const child = child_process.fork('child.js')

child.send('Ping child')

child.on('message', code => console.log(`Message to parent: ${code}`))

child.on('close', code => console.log(`Child process exited. Code: ${code}`))

child.js

console.log(`Child process is running`)

process.on('message', message => console.log('Message to child: ', message))

process.send('Ping parent')

Результат должен быть таким.

Child process is running
Message to child:  Ping child
Message to parent: Ping parent

Завершение дочернего процесса можно инициировать вызовом метода disconnect() или exit(). Вызов disconnect() закроет IPC канал для обмена сообщениями, сгенерирует событие disconnect и завершит процесс после выполнения всех его операций.

Внесем изменения в предыдущий пример в файл child.js.

console.log(`Child process is running`)

process.on('message', message => console.log('Message to child: ', message))

process.send('Ping parent')
process.exit()

Теперь в консоли должна быть выведена дополнительная строка.

Child process exited. Code: 0