美文网首页
Node 学习笔记

Node 学习笔记

作者: _于曼丽_ | 来源:发表于2022-04-27 16:23 被阅读0次

结束进程

有些程序可以自动结束,如果事件循环中没有其他待处理的工作,则 Node.js 进程将自行退出,退出码为 process.exitCode 或者 0,这种情况会触发 exit 事件,不会触发 signal 事件。

有些程序无法自动结束,例如 Node.js 启动 HTTP 服务器,则该进程一直在监听客户端的请求,无法自动结束。如果我们想要结束该进程,可以通过两种方式:调用 process.exit() 或者发送 signal 信号。

退出码

一个 Node.js 进程不管以什么方式结束,都会有一个退出码。在命令行终端可以通过 echo $? 来查看上一个退出进程的退出码。

常用退出码

  • 0:正常退出
  • 1:发生未捕获错误
  • 5:V8 引擎执行错误
  • 8:不正确的参数
  • 128 + 信号值:接收到 signal 信号

process.exit()

调用 process.exit(code) 结束进程,任何仍在事件循环中排队的其他工作被丢弃,这意味着任何待处理的回调、任何仍在发送的网络请求、任何文件系统访问、或者正在写入 stdout 或 stderr 的进程,所有这些都将立即被非正常地终止。因此不推荐以这种方式结束进程。

如果没有指定退出码,则使用默认值 0

// 以下两种方式相同
process.exit()
process.exit(0)

可以通过 process.exitCode 指定退出码的默认值

process.exitCode = 1
// 以下两种方式相同
process.exit()
process.exit(1)

调用 process.exit() 会触发 exit 事件(不会触发 signal 事件),一旦所有 exit 监听器都运行完毕,则 Node.js 进程将终止

process.on('exit', code => {
  console.log(`Exit with code ${code}`)
})
process.exit(1)

监听器函数必须只执行同步的操作

process.on('exit', code => {
  setTimeout(() => {
    // exit 监听器执行之后,Node.js 进程将终止,任何仍在事件循环中排队的其他工作被丢弃
    // 以下代码不会执行
    console.log('This will not run');
  }, 0)
})

发送 signal 信号

常用信号

  • SIGINT
  • SIGHUP
  • SIGTERM 正常终止
  • SIGKILL 立即终止,类似 process.exit()

发送信号

  • 终端:ctrl + C 发送 SIGINT 信号
  • 终端:kill -signal pid
  • 代码:process.kill(pid, signal)

调用 process.kill(pid, signal) 只是向指定的进程发送一个信号,就像在终端使用 kill -signal pid 指令发送信号一样。具体是否会结束该进程,还要看该进程的代码中的信号事件绑定的监听器是如何工作的。

在一个 Node.js 程序中可以向任意一个进程发送信号

// 向 pid 为 3227 的进程发送 SIGTERM 信号
process.kill(3227, 'SIGTERM')

也可以向当前代码所在的进程发送信号

// process.pid 为当前进程的 pid
process.kill(process.pid, 'SIGTERM')

信号事件

当 Node.js 进程接收到一个信号时,会触发信号事件

  • 如果没有为某个信号指定监听器,当 Node.js 进程收到该信号的时候,使用默认的监听器。
  • SIGTERM SIGINT SIGHUP 默认的监听器,会以代码128 + signal number 结束进程。
  • SIGTERM SIGINT SIGHUP 绑定自定义的监听器,原有默认的行为会被移除 (Node.js 进程不会结束)。
  • SIGKILL 不能绑定自定义的监听器,当 Node.js 进程接收到该信号会使得 Node.js无条件终止。
process.on('SIGTERM', () => {
  // 当前进程接收到 SIGTERM 信号,会调用该监听器
  // 由于监听器里面没有代码能够结束当前进程,所以当前进程不会结束
  // 如果不指定 SIGTERM 信号的监听器,当前进程接收到 SIGTERM 信号,会调用默认的监听器
  // 默认的监听器会结束当前进程,退出码为 128 + 15,其中 15 为 SIGTERM 的 signal number
  // 默认的监听器不会触发 exit 事件
  console.log('当前进程接收到 SIGTEM 信号')
})
kill -SIGTERM 2587

向一个无法自动结束的进程发送信号,不管是通过代码发送信号 process.kill(pid, signal),还是通过终端发送信号 kill -signal pid,只会触发 signal 事件,不会触发 exit 事件,除非在绑定的信号监听器里面执行 process.exit() 退出进程。

process.on('SIGTERM', () => {
  console.log('当前进程接收到 SIGTEM 信号')
  // 以下命令会触发 exit 事件
  process.exit(0)
})

process.on('exit', (code) => {
  console.log(`Exit with code ${code}`)
})
kill -SIGTERM 2587

相关文章

网友评论

      本文标题:Node 学习笔记

      本文链接:https://www.haomeiwen.com/subject/jmpkyrtx.html