源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
查看: 27|回复: 13

[JavaScript] 浅谈Node.js 子进程与应用场景

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2018-1-24 10:42:47 | 显示全部楼层 |阅读模式
这篇文章主要介绍了浅谈Node.js 子进程与应用场景,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

背景

由于ons(阿里云 RocketMQ 包)基于 C艹 封装而来,不支持单一进程内实例化多个生产者与消费者,为了解决这一问题,使用了 Node.js 子进程。

在使用的过程中碰到的坑

发布:进程管理关闭主进程后,子进程变为操作系统进程(pid 为 1)

几种解决方案

将子进程看做独立运行的进程,记录 pid,发布时进程管理关闭主进程同时关闭子进程

主进程监听关闭事件,主动关闭从属于自己的子进程

子进程种类

  1. spawn:执行命令
  2. exec:执行命令(新建 shell)
  3. execFile:执行文件
  4. fork:执行文件

子进程常用事件

  1. exit
  2. close
  3. error
  4. message

close 与 exit 是有区别的,close 是在数据流关闭时触发的事件,exit 是在子进程退出时触发的事件。因为多个子进程可以共享同一个数据流,所以当某个子进程 exit 时不一定会触发 close 事件,因为这个时候还存在其他子进程在使用数据流。

子进程数据流

  1. stdin
  2. stdout
  3. stderr

因为是以主进程为出发点,所以子进程的数据流与常规理解的数据流方向相反,stdin:写入流,stdout、stderr:读取流。

spawn

spawn(command[, args][, options])

执行一条命令,通过 data 数据流返回各种执行结果。

基础使用

const { spawn } = require('child_process');

const child = spawn('find', [ '.', '-type', 'f' ]);
child.stdout.on('data', (data) => {
  console.log(`child stdout:\n${data}`);
});

child.stderr.on('data', (data) => {
  console.error(`child stderr:\n${data}`);
});

child.on('exit', (code, signal) => {
  console.log(`child process exit with: code $[code], signal: ${signal}`);
});

常用参数

{
  cwd: String,
  env: Object,
  stdio: Array | String,
  detached: Boolean,
  shell: Boolean,
  uid: Number,
  gid: Number
}

重点说明下 detached 属性,detached 设置为 true 是为子进程独立运行做准备。子进程的具体行为与操作系统相关,不同系统表现不同,Windows 系统子进程会拥有自己的控制台窗口,POSIX 系统子进程会成为新进程组与会话负责人。

这个时候子进程还没有完全独立,子进程的运行结果会展示在主进程设置的数据流上,并且主进程退出会影响子进程运行。当 stdio 设置为 ignore 并调用 child.unref(); 子进程开始真正独立运行,主进程可独立退出。

exec

exec(command[, options][, callback])

执行一条命令,通过回调参数返回结果,指令未执行完时会缓存部分结果到系统内存。

const { exec } = require('child_process');

exec('find . -type f | wc -l', (err, stdout, stderr) => {
  if (err) {
    console.error(`exec error: ${err}`);
    return;
  }

  console.log(`Number of files ${stdout}`);
});

两全其美 —— spawn 代替 exec

由于 exec 的结果是一次性返回,在返回前是缓存在内存中的,所以在执行的 shell 命令输出过大时,使用 exec 执行命令的方式就无法按期望完成我们的工作,这个时候可以使用 spawn 代替 exec 执行 shell 命令。

const { spawn } = require('child_process');

const child = spawn('find . -type f | wc -l', {
  stdio: 'inherit',
  shell: true
});

child.stdout.on('data', (data) => {
  console.log(`child stdout:\n${data}`);
});

child.stderr.on('data', (data) => {
  console.error(`child stderr:\n${data}`);
});

child.on('exit', (code, signal) => {
  console.log(`child process exit with: code $[code], signal: ${signal}`);
});

execFile

child_process.execFile(file[, args][, options][, callback])

执行一个文件

与 exec 功能基本相同,不同之处在于执行给定路径的一个脚本文件,并且是直接创建一个新的进程,而不是创建一个 shell 环境再去运行脚本,相对更轻量级更高效。但是在 Windows 系统中如 .cmd 、 .bat 等文件无法直接运行,这是 execFile 就无法工作,可以使用 spawn、exec 代替。

fork

child_process.fork(modulePath[, args][, options])

执行一个 Node.js 文件

// parent.js

const { fork } = require('child_process');

const child = fork('child.js');

child.on('message', (msg) => {
  console.log('Message from child', msg);
});

child.send({ hello: 'world' });
// child.js

process.on('message', (msg) => {
  console.log('Message from parent:', msg);
});

let counter = 0;

setInterval(() => {
  process.send({ counter: counter++ });
}, 3000);

fork 实际是 spawn 的一种特殊形式,固定 spawn Node.js 进程,并且在主子进程间建立了通信通道,让主子进程可以使用 process 模块基于事件进行通信。

子进程使用场景

  1. 计算密集型系统
  2. 前端构建工具利用多核 CPU 并行计算,提升构建效率
  3. 进程管理工具,如:PM2 中部分功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

回复

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2022-9-22 12:38:25 | 显示全部楼层
好东西可以可以可以可以
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

66

积分

注册会员

Rank: 2

积分
66
发表于 2023-9-12 06:11:46 | 显示全部楼层
刷屏刷屏刷屏
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

321

积分

中级会员

Rank: 3Rank: 3

积分
321
发表于 2023-10-19 05:39:07 | 显示全部楼层
天天源码社区。。。。
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

69

积分

注册会员

Rank: 2

积分
69
发表于 2024-3-2 00:36:58 | 显示全部楼层
女生看了弄丢了卡萨诺的卡洛斯
回复 支持 反对

使用道具 举报

6

主题

2万

回帖

247

积分

中级会员

Rank: 3Rank: 3

积分
247
发表于 2024-3-2 09:04:21 | 显示全部楼层
66666666666666666666
回复 支持 反对

使用道具 举报

6

主题

2万

回帖

425

积分

中级会员

Rank: 3Rank: 3

积分
425
发表于 2024-3-31 00:38:40 | 显示全部楼层
女生看了弄丢了卡萨诺的卡洛斯
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

380

积分

中级会员

Rank: 3Rank: 3

积分
380
发表于 2024-4-1 00:05:45 | 显示全部楼层
还可以不错
回复 支持 反对

使用道具 举报

1

主题

1万

回帖

93

积分

注册会员

Rank: 2

积分
93
发表于 2024-6-10 19:54:37 | 显示全部楼层
天天源码社区论坛
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2024-8-19 12:43:01 | 显示全部楼层
66666666666666666666
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2024-11-25 21:52 , Processed in 0.152054 second(s), 26 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表