进程管理
在 Node.js 中,进程(process)是一个重要的概念,它代表了 Node.js 应用程序的运行实例。Node.js 提供了一个全局对象 process,它提供了操作系统相关的信息和与当前进程交互的方法。
1. 全局 process 对象
process 是一个 Node.js 的全局对象,无需 require 即可使用。
常用属性:
process.pid: 当前进程的 PID(进程 ID)。process.platform: 当前运行平台(如win32,linux,darwin)。process.arch: 当前 CPU 架构(如x64,arm)。process.cwd(): 获取当前工作目录。process.env: 环境变量的对象,可以通过process.env.VARIABLE_NAME访问变量。process.argv: 一个数组,包含命令行参数。第一个元素是 Node.js 的可执行文件路径,第二个元素是脚本文件路径,后续是传入的参数。
2. 进程的输入/输出
process.stdin标准输入流,可用于接收用户输入。process.stdout标准输出流,用于输出信息。process.stderr标准错误流,用于输出错误信息。
js
// 示例:接收用户输入并输出
process.stdin.on('data', (data) => {
process.stdout.write(`You entered: ${data}`)
})3. 管理生命周期
退出进程
process.exit(code)强制终止进程。code是退出码,默认为0(表示成功)。
js
process.exit(1) // 非零退出表示错误事件监听
process.on(event, listener)监听进程事件,比如exit、uncaughtException、SIGINT等。
js
process.on('exit', (code) => {
console.log(`Process exited with code: ${code}`)
})
process.on('uncaughtException', (err) => {
console.error('Uncaught exception:', err)
})4. 子进程(Child Processes)
Node.js 提供了 child_process 模块 来创建和管理子进程,以实现任务的并行化。
spawn
spawn:启动一个新进程,适合长时间运行任务。
js
import { spawn } from 'node:child_process'
const ls = spawn('ls', ['-lh', '/usr'])
ls.stdout.on('data', (data) => {
console.log(`Output: ${data}`)
})
ls.stderr.on('data', (data) => {
console.error(`Error: ${data}`)
})
ls.on('close', (code) => {
console.log(`Child process exited with code ${code}`)
})exec
exec:执行一条 shell 命令,适合简短任务。
js
import { exec, execSync } from 'node:child_process'
export function $(pieces) {
const cmd = $.prefix + pieces[0]
return new Promise((resolve, reject) => {
const child = exec(cmd, {
windowsHide: true,
// Shell to execute the command with
shell: $.shell,
// Current working directory of the child process.
cwd: undefined,
})
let stdout = ''
child.stdout.on('data', (data) => {
process.stdout.write(data)
stdout += data
})
let stderr = ''
child.stderr.on('data', (data) => {
process.stderr.write(data)
stderr += data
})
child.on('exit', (code) => {
(code === 0 ? resolve : reject)({
stdout,
stderr,
})
})
})
}
// Try `command`, should cover all Bourne-like shells.
// Try `which`, should cover most other cases.
// Try `type` command, if the rest fails.
$.shell = `${execSync('command -v bash || which bash || type -p bash')}`.trim()
$.prefix = 'set -euo pipefail;'
$`cat package.json | grep name`execFile
execFile:直接执行文件,不通过 shell。
fork
fork:专用于创建 Node.js 子进程。
js
import { fork } from 'node:child_process'
const child = fork('worker.js')
child.on('message', (message) => {
console.log('child:', message)
})
child.send('master message')5. 信号处理
Node.js 支持通过信号与进程交互(如 SIGINT、SIGTERM)。
js
process.on('SIGINT', () => {
console.log('Received SIGINT. Press Ctrl+C again to exit.')
})小结
process提供与操作系统交互的接口。- 子进程模块 可以创建和管理子任务。
- 通过事件和信号,可以精细地控制进程生命周期。
Node.js 的进程管理能力使其在构建服务器、CLI 工具和多任务应用时非常强大。
Reference