После недели тупикового процесса я, наконец, разобрался в непонятных и сложных документах, готов поделиться своим пониманием со всеми, и надеюсь, что каждый может высказать свое мнение.
концепция процесса
- В Node.js каждое приложение является экземпляром класса процесса.
- Приложение представлено объектом процесса, который является глобальным объектом, с помощью которого можно получить свойства, методы и события приложения Node.jsy, а также различную информацию, такую как пользователь и среда, в которой запущена программа.
Несколько важных свойств в процессе
- stdin Стандартный входной читаемый поток
- stdout стандартный входной поток с возможностью записи
- Стандартный поток вывода ошибок stderr
- массив входных аргументов терминала argv
- env информация о среде ОС
- идентификатор процесса приложения 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
технологический метод
- process.memoryUsage() Просмотр информации об использовании памяти
- process.nextTick() Функция обратного вызова выполняется после выполнения текущего цикла обработки событий.
- process.chdir() Метод chdir используется для изменения текущего рабочего каталога, используемого в приложении Node.js.
- process.cwd() Текущий рабочий каталог процесса
- process.kill() убивает процесс
- 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(команда, [аргументы], [параметры])
- команда Параметр, который должен быть указан, указывает команду, которая должна быть выполнена
- массив args, в котором хранятся все параметры, необходимые для запуска команды
- Параметр 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 запускает дочерний процесс
- Создайте новый процесс Node.js и вызовите указанный модуль, установив канал связи IPC, который позволяет родительскому и дочернему процессам отправлять сообщения друг другу.
- Метод fork возвращает неявно созданный объект ChildProcess, представляющий дочерний процесс.
- После завершения операции ввода/вывода дочернего процесса дочерний процесс не завершится автоматически и должен использовать метод 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)
})