процесс узла и child_process

Node.js внешний интерфейс Операционная система Mac

После недели тупикового процесса я, наконец, разобрался в непонятных и сложных документах, готов поделиться своим пониманием со всеми, и надеюсь, что каждый может высказать свое мнение.

концепция процесса

  1. В Node.js каждое приложение является экземпляром класса процесса.
  2. Приложение представлено объектом процесса, который является глобальным объектом, с помощью которого можно получить свойства, методы и события приложения Node.jsy, а также различную информацию, такую ​​как пользователь и среда, в которой запущена программа.

Несколько важных свойств в процессе

  1. stdin Стандартный входной читаемый поток
  2. stdout стандартный входной поток с возможностью записи
  3. Стандартный поток вывода ошибок stderr
  4. массив входных аргументов терминала argv
  5. env информация о среде ОС
  6. идентификатор процесса приложения pid

стандартный ввод и стандартный вывод

process.stdin.on('data', (chunk) => {
  process.stdout.write('进程接收到数据' + chunk)
})

результат операции

argv

console.log(process.env)

env: введите export NODE_ENV=develop в терминал Mac

console.log(process.env.NODE_ENV) //develop

технологический метод

  1. process.memoryUsage() Просмотр информации об использовании памяти
  2. process.nextTick() Функция обратного вызова выполняется после выполнения текущего цикла обработки событий.
  3. process.chdir() Метод chdir используется для изменения текущего рабочего каталога, используемого в приложении Node.js.
  4. process.cwd() Текущий рабочий каталог процесса
  5. process.kill() убивает процесс
  6. process.uncaughtException() Запускает событие uncaughtException объекта процесса, когда приложение генерирует неперехваченное исключение.
say() //方法不存在
process.on('uncaughtException',function(err){
  console.log('捕获到一个未被处理的错误:',err);
});

child_process

Подпроцесс в центре внимания сегодняшнего разговора. Я также не понимаю некоторые вещи. Я надеюсь общаться с вами больше.

Фон, на котором появляется child_process

В Node.js все операции выполняются только одним потоком. Если операция потребляет много ресурсов ЦП, последующие операции должны ждать.

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

spawn

Синтаксис: child_process.spawn(команда, [аргументы], [параметры])

  1. команда Параметр, который должен быть указан, указывает команду, которая должна быть выполнена
  2. массив args, в котором хранятся все параметры, необходимые для запуска команды
  3. Параметр options — это объект, указывающий параметры, используемые при запуске дочернего процесса.
const { spawn } = require('child_process')
const path = require('path')

let child1 = spawn('node', ['test1.js', 'yanyongchao'], {
    stdio: ['pipe', 'pipe', 'pipe'], // 三个元素数组 下面会详解
    cwd: __dirname, 子进程工作目录
    env: process.env, 环境变量
    detached: true // 如果为true,当父进程不存在时也可以独立存在
})

На самом деле вышеизложенное легко понять кроме массива sdtio, давайте вместе разберем stdio

stdio

stdio — это массив, используемый для установки стандартного ввода, стандартного вывода и вывода ошибок. личное понимание

pipe: устанавливает канал между родительским процессом и дочерним процессом

код основного процесса

const path = require('path')
const { spawn } = require('child_process')

let p = spawn('node', ['childs_t.js'], {
  cwd: path.join(__dirname, 'childs'),
  stdio: ['pipe', 'pipe', process.stderr]
})

p.stdout.on('data', (data) => {
  console.log(data.toString())
}) 
// 这里用stdout原因: 子进程的数据流与常规理解的数据流方向相反,
// stdin:写入流,stdout、stderr:读取流。

код подпроцесса

process.stdout.write('asd')

Если вы поместите поток в stdio, process.stdout, process.stdin

код основного процесса

const { spawn } = require('child_process')
const path = require('path')


// 如果放的是一个流,则意味着父进程和子进程共享一个流
const p = spawn('node', ['child_t.js'], {
  cwd: path.join(__dirname, 'childs'),
  stdio: [process.stdin, process.stdout, process.stderr]
})

код подпроцесса

process.stdout.write('asd') //控制台会输出asd

ipc

код основного процесса

const path = require('path')
const { spawn } = require('child_process')

let p = spawn('node', ['child_t.js'], {
  cwd: path.join(__dirname, 'childs'),
  stdio: ['ipc', 'pipe', 'pipe']
})

p.on('message', (msg) => {
  console.log(msg)
})

p.send('hello chhild_process')

код подпроцесса

process.on('message', (msg) => {
  process.send('子进程' + msg)
})
// child.send(message,[sendHandle]);//在父进程中向子进程发送消息
// process.send(message,[sendHandle]);//在子进程中向主进程发送消息

отдельный режим

const { spawn } = require('child_process')
const fs = require('fs')
const path = require('path')
let out = fs.openSync(path.join(__dirname, 'childs/msg.txt'), 'w', 0o666)

let p = spawn('node', ['test4.js'], {
  detached: true, //保证父进程结束,子进程仍然可以运行
  stdio: 'ignore',
  cwd: path.join(__dirname, 'childs')
})

p.unref()

p.on('close', function() {
  console.log('子进程关闭')
})

p.on('exit', function() {
  console.log('子进程退出')
})

p.on('error', function(err) {
  console.log('子进程1开启失败' + err)
})

fork запускает дочерний процесс

  1. Создайте новый процесс Node.js и вызовите указанный модуль, установив канал связи IPC, который позволяет родительскому и дочернему процессам отправлять сообщения друг другу.
  2. Метод fork возвращает неявно созданный объект ChildProcess, представляющий дочерний процесс.
  3. После завершения операции ввода/вывода дочернего процесса дочерний процесс не завершится автоматически и должен использовать метод process.exit() для явного выхода.

код подпроцесса

const { fork } = require('child_process')
const path = require('path')
let child = fork(path.join(__dirname, 'childs/fork1.js'))

child.on('message', (data) => {
  console.log('父进程接收到消息' + data)
})

child.send('hello fork')

child.on('error', (err) => {
  console.error(err)
})

код подпроцесса

process.on('message', (m, setHandle) => {
  console.log('子进程接收到消息' + m)
  process.send(m) //sendHandle是一个 net.Socket 或 net.Server 对象
})

exec запускает дочерний процесс

// exec同步执行一个shell命令
let { exec } = require('child_process')
let path = require('path')

// 用于使用shell执行命令, 同步方法

let p1 = exec('node exec.js a b c', {cwd: path.join(__dirname, 'childs')}, function(err, stdout, stderr) {
  console.log(stdout)
})

EXECFILE открывает подпроцесс

let { execFile } = require('child_process')
let path = require('path')

let p1 = execFile('node', ['exec.js', 'a', 'b', 'c'], {
  cwd: path.join(__dirname, 'childs')
}, function(err, stdout, stderr) {
  console.log(stdout)
})