Node.js 本身是一个单线程的模式,但有些时候还是需要子进程的模式来处理某些需求

child_process 模块

该模块有一些方法能创建子进程

  1. //exec、spawn: 创建子进程、执行shell 命令
  2. //前者返回的进程创建缓存结果。后者返回的是一个 stream 流
  3. const { exec, spawn } = require('child_process');
  4. /*
  5. 三个参数:
  6. 1. shell 命令
  7. 2. 配置项:一般不用专门配置
  8. 3. 回调函数:也是传入三个参数
  9. a.创建子进程时的错误
  10. b. 创建成功后 shell 命令也成功
  11. c. 创建成狗后 shell 命令失败
  12. */
  13. /* exec('cat a.js', { shell: true, encoding: 'utf8' }, (error, stdout, stderr) => {
  14. // console.log(error);
  15. if (error) {
  16. console.log('报错了');
  17. return;
  18. }
  19. console.log(`stderr:${stderr}`);
  20. console.log(`stdout:${stdout}`);
  21. });
  22. */
  23. /*
  24. 三个参数:
  25. 1. shell 头
  26. 2. 数组 shell 后面
  27. 3. 配置项
  28. */
  29. const ls = spawn('ls', ['-a'], {
  30. encoding: 'utf8',
  31. shell: true,
  32. cwd: undefined,
  33. env: process.env,
  34. });
  35. ls.stdout.on('data', (data) => {
  36. console.log(`stdout:${data}`);
  37. });
  38. ls.stderr.on('data', (data) => {
  39. console.log(`stderr:${data}`);
  40. });
  41. ls.on('close', (code) => {
  42. console.log(`close:${code}`);
  43. });

cluster 模块

协助开发者利用 CPU。
正常情况下,Node 只能利用 CPU 中的某一个内核,就会产生一些资源利用上的浪费,利用该模块就能充分利用 CPU 的资源。

PID( 进程控制符 )英文全称为Process Identifier,它也属于 电工电子 类技术术语。 PID是各进程的代号,每个进程有唯一的PID编号。 它是进程运行时系统分配的,并不代表专门的进程。 在运行时PID是不会改变标识符的,但是进程终止后PID标识符就会被系统回收,就可能会被继续分配给新运行的程序。

  1. const cluster = require('cluster');
  2. const http = require('http');
  3. const os = require('os');
  4. const cpus = os.cpus().length;
  5. // console.log(cpus);
  6. if (cluster.isMaster) {
  7. console.log(`主进程:${process.pid}已经启动`);
  8. //衍生工作进程
  9. for (let index = 0; index < cpus; index++) {
  10. cluster.fork();
  11. }
  12. } else {
  13. //工作进程可以共享任何 tcp 连接
  14. //这里共享的是 http 的服务器
  15. http
  16. .createServer((req, res) => {
  17. res.writeHead(200, {
  18. 'Content-Type': 'text/html;charset=utf-8',
  19. });
  20. res.write('hello');
  21. res.end();
  22. })
  23. .listen(8000);
  24. console.log(`工作进程${process.pid}已经启动`);
  25. }

master 进程与 cluster 进程的通信

master.js

  1. const { fork } = require('child_process');
  2. const child = fork('./child.js');
  3. child.on('message', (msg) => {
  4. console.log(`来自子进程:${msg}`);
  5. });
  6. child.send('来自master');

child.js

  1. console.log(`子进程${process.pid}`);
  2. process.on('message', (msg) => {
  3. console.log(`来自master:${msg}`);
  4. });
  5. process.send('这是子进程');

image.png