Skip to content

进程管理

在 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) 监听进程事件,比如 exituncaughtExceptionSIGINT 等。
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 支持通过信号与进程交互(如 SIGINTSIGTERM)。

js
process.on('SIGINT', () => {
  console.log('Received SIGINT. Press Ctrl+C again to exit.')
})

小结

  • process 提供与操作系统交互的接口。
  • 子进程模块 可以创建和管理子任务。
  • 通过事件和信号,可以精细地控制进程生命周期。

Node.js 的进程管理能力使其在构建服务器、CLI 工具和多任务应用时非常强大。

Reference