ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >[warning] 说明:本文档只说明使用频繁的知识点,有关对应知识的所有具体内容可查看对应的 API 连接 # 1. procss 进程 **`process`对象是一个全局变量,提供有关当前 Node.js 进程的信息并对其进行控制。** **`process` 全部事件与属性查看官方文档:[http://nodejs.cn/api/process.html#process\_process](http://nodejs.cn/api/process.html#process_process)** ## 1.1 常用的事件 * ### 1.1.1 beforeExit * node.js 在没有工作调度时会退出(进程结束),此时会优先触发 beforeExit 函数 * 监听 beforeExit 注册的函数可以异步调用,从而继续进程(开始新的工作调度) * 监听函数将传入 process.exitCode * 显式终止时不会触发 beforeExit ~~~ // 监听函数 process.on('beforeExit', (code) => { console.log('进程 beforeExit 事件的代码: ', code); }); console.log('此消息最新显示'); // 显式终止 process.exit(); 此消息最新显示 进程 exit 事件的代码: 0 ~~~ * ### 1.1.2 exit * 进程结束时触发函数 * 监听函数将传入 process.exitCode * 监听函数内只可同步执行,异步函数无效 ~~~ process.on('exit', (code) => { console.log('进程 exit 事件的代码: ', code); }); process.on('beforeExit', (code) => { console.log('进程 beforeExit 事件的代码: ', code); }); console.log('此消息最新显示'); 此消息最新显示 进程 beforeExit 事件的代码: 0 进程 exit 事件的代码: 0 ~~~ * ### 1.1.3 message * 如果使用 IPC 通道衍生 Node.js 进程(在子进程与集群会常用),则只要子进程收到父进程的消息,就会触发事件 * ### 1.1.4 disconnect * 在 IPC 通道关闭时触发事件,并更改 `process.connected` 为 `false` * 进程调用`process.disconnect()`的效果和父进程调用[`ChildProcess.disconnect()`](http://nodejs.cn/s/ke6TNp)的一样。 * ### 1.1.5 nextTick * 将回调函数添加到下一个时间点的队列 ~~~ console.log('开始'); process.nextTick(() => { console.log('下一个时间点的回调'); }); console.log('调度'); 开始 调度 下一个时间点的回调 ~~~ ## 1.2 常用的属性 * ### 1.2.1 env * process.env 返回包含用户环境的对象 * 进程内可 `增 删 改` 对象属性 ~~~ process.env.TEST = 1; console.log(process.env.TEST); // 1 delete process.env.TEST; console.log(process.env.TEST); // => undefined ~~~ * ### 1.2.2 exitCode * 进程退出时的退出码 * process.exit(code) 可通过 exit 方法指定退出码 * ### 1.2.3 pid * 进程标识 PID * ### 1.2.4 ppid * 父进程标识 PID # 2. child_procss 子进程 **`child_procss ` 全部事件与属性查看官方文档:[http://nodejs.cn/api/child\_process.html#child\_process\_child\_process](http://nodejs.cn/api/child_process.html#child_process_child_process)** ## 2.1 创建异步进程 > 创建异步进程的每一个方法都会返回一个 `ChildProcess` 实例 * ### 2.1.1 fork * 该方法是 `child_process.spawn()` 的一个特例,专门用于衍生新的 Node.js 进程 * 衍生的 Node.js 子进程独立于父进程,但两者之间建立的 IPC 通信通道除外 * 通过 fork 创建的子进程可与父进程互发消息 ~~~ const childProcess=require('child_process'); const parent = childProcess.fork('child.js'); parent.send('server', () => { console.log('父子进程建立连接'); }); // child.js process.on('message', function (msg) { if (msg === 'server') { console.log('子进程收到消息'); } }) ~~~ * ### 2.1.2 spawn * 该方法使用给定的`command`衍生一个新进程,并带上`args`中的命令行参数 ~~~ const childProcess=require('child_process'); const sp = childProcess.spawn('node',['test1.js'],{ cwd:'./test' }); sp.stdout.on('data',function (data) { console.log('子进程标准输出: '+ data); sp2.stdin.write(data); }); sp.on('exit',function(code, signal) { if (code || code === 0) { console.log('子进程退出,退出代码为:' + code); } else { console.log('子进程退出,退出信号为:' + signal); } }); ~~~ ## 2.2 创建同步进程 > 同步进程将会阻塞 Node.js 事件循环、暂停任何其他代码的执行 * ### 2.2.1 spawnSync * spawn 同步版,在子进程完全关闭之前该函数不会返回 ## 2.3 ChildProcess 类 **ChildProcess 实例代表衍生的子进程** **实例通过异步创建进程而生成** ***** **常用事件** * ### 2.3.1 disconnect * 断开连接后不能再发法消息,且更改 `subprocess.connected` 属性为`false`,与 `process ` 同名事件使用效果相似 * 调用父进程中的`subprocess.disconnect()`与子进程中的`process.disconnect()`效果一致 * ### 2.3.2 close * 子进程 stdio 流被关闭时触发 * 与 exit 事件不同,多个进程可能共享同一个 stdio 流 > `options.stdio`选项用于配置在父进程和子进程之间建立的管道 ~~~ const { spawn } = require('child_process'); const ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', (data) => { console.log(`stdout: ${data}`); }); ls.on('close', (code) => { console.log(`子进程使用代码 ${code} 关闭所有 stdio`); }); ls.on('exit', (code) => { console.log(`子进程使用代码 ${code} 退出`); }); ~~~ * ### 2.3.3 exit * 进程结束后触发 * sp.on('exit', (code, single) => {}) code 与 single 两个值至少一个不为 null * ### 2.3.5 subprocess.send * * ### 2.3.4 message * 子进程使用 process.send() 发送消息时触发 **常用属性** * ### 2.3.5 subprocess.channel * 表示子进程的 IPC 通道 * ### 2.3.6 subprocess.connected * 表明是否可以从子进程发送和接收消息 * 为 false 时不可发送或接受消息 * ### 2.3.7 subprocess.stdio * 一个到子进程的管道的稀疏数组,对应于传给[`child_process.spawn()`](http://nodejs.cn/s/CKoDGf)的被设为`'pipe'`值的[`stdio`](http://nodejs.cn/s/ixmPX9)选项中的位置。`subprocess.stdio[0]`、`subprocess.stdio[1]`和`subprocess.stdio[2]`也分别可用作`subprocess.stdin`、`subprocess.stdout`和`subprocess.stderr`。 * ### 2.3.8 subprocess.stdout * 子进程的`stdout`的可读流。 * `subprocess.stdout` = `subprocess.stdio[1]` ; `stdio[1]`被设置为`'pipe'`以外的任何值,则该值将会是`null` # 3. cluster 集群 **该模块可以创建共享服务器端口的子进程。** **单个 Node.js 实例运行在单个线程中,通过启用一组 Node.js 进程,来充分利用多核系统** **有关集群的全部内容可查看官方文档:[http://nodejs.cn/api/cluster.html#cluster\_cluster](http://nodejs.cn/api/cluster.html#cluster_cluster)** ~~~ const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`主进程 ${process.pid} 正在运行`); // 衍生工作进程。 for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`工作进程 ${worker.process.pid} 已退出`); }); } else { // 工作进程可以共享任何 TCP 连接。 // 在本例子中,共享的是 HTTP 服务器。 http.createServer((req, res) => { res.writeHead(200); res.end('你好世界\n'); }).listen(8000); console.log(`工作进程 ${process.pid} 已启动`); } 主进程 2796 正在运行 工作进程 14360 已启动 工作进程 12140 已启动 工作进程 6276 已启动 工作进程 14372 已启动 ~~~ ## 3.1 work 类 > 工作进程由`child_process.fork()`方法创建,因此它们可以使用 IPC 和父进程通信,从而使各进程交替处理连接服务。 **常用事件** * ### 3.1.1 disconnect * 特定于此工作进程 ~~~ cluster.fork().on('disconnect', () => { // 工作进程已断开连接。 }); ~~~ **常用属性** * ### 3.1.2 worker.id * 工作进程的标识 * ### 3.1.3 worker.process * 为 child_process.fork() 返回的对象 * 在工作进程中为全局对象 ## 3.2 常用事件 * ### 3.2.1 fork * 新的工作进程被衍生时触发 * 可用来记录工作进程活动 > 可以直接调用衍生新的工作进程 ~~~ const timeouts = []; function errorMsg() { console.error('连接出错'); } cluster.on('fork', (worker) => { timeouts[worker.id] = setTimeout(errorMsg, 2000); }); cluster.on('listening', (worker, address) => { clearTimeout(timeouts[worker.id]); }); cluster.on('exit', (worker, code, signal) => { clearTimeout(timeouts[worker.id]); errorMsg(); }); ~~~ * ### 3.2.2 exit * 任何工作进程关闭时触发 * 可用于重启工作进程 ~~~ cluster.on('exit', (worker, code, signal) => { console.log('工作进程 %d 关闭 (%s). 重启中...', worker.process.pid, signal || code); cluster.fork(); }); ~~~ * ### 3.2.3 online * 衍生工作进后,工作进程运行时触发 * 主进程衍生工作进程时触发`'fork'` 而不是 online ~~~ cluster.on('online', (worker) => { console.log('工作进程被衍生后响应'); }); ~~~ ## 3.3 常用属性 * ### 3.3.1 cluster.isMaster * 该进程为主进程时为 true * ### 3.3.2 cluster.isWorker * 不为主进程时为 true * ### 3.3.3 cluster.worker * 当前工作进程对象 ~~~ const cluster = require('cluster'); if (cluster.isMaster) { console.log('这是主进程'); cluster.fork(); cluster.fork(); } else if (cluster.isWorker) { console.log(`这是工作进程 #${cluster.worker.id}`); } ~~~ * ### 3.3.4 cluster.workers * 存储所有活跃工作进程对象 * 工作进程断开连接以及推出后从workers中移除 ~~~ // 遍历所有工作进程。 function eachWorker(callback) { for (const id in cluster.workers) { callback(cluster.workers[id]); } } eachWorker((worker) => { worker.send('通知所有工作进程'); }); ~~~