JS在线运行

版本:

所属目录
点击了解高性能代码运行API
运行结果
教程手册
代码仓库
极速运行
终端运行
图形+终端

                        
以下是用户最新保存的代码
check in balalal 发布于:2025-04-26 17:54 最近一次给学姐的代码 发布于:2025-04-26 13:13 JS AES128加解密 发布于:2025-04-21 13:44 最小矩阵宽度(从第一列开始一列列加,直到判断子矩阵内包含数组的所有元素) 发布于:2025-04-16 19:10 最小交付时间(二分+回溯:先将数组排序,最小值start=Math.max(arr),最大值end = arr.reduce,回溯中创建一个新的工人数组,每次遍历数组时将数组中的每一个元素都尝试分配给worker[i]) 发布于:2025-04-16 18:53 阿里巴巴找黄金宝箱Ⅳ(单调栈:栈中存储单调递减的元素的集合,当找到比栈顶元素大的元素时,循环出栈直到栈顶元素不小于当前元素) 发布于:2025-04-15 17:47 找出经过特定点的路径长度(dfs+回溯) 发布于:2025-04-14 16:32 计算最接近的数(1.输入处理;2.对数组进行深拷贝,然后对新数组进行排序,之后在进行后续操作) 发布于:2025-04-14 15:11 MELON的难题(01背包问题:先判断数组和是否为偶数,如果为偶数直接输出-1,target=sum/2 状态转移方程dp[i]=Math.min(dp[i],dp[i-1]+1) 发布于:2025-04-11 17:29 简易内存池(模拟,双指针) 发布于:2025-04-11 17:12 通过软盘拷贝文件 这是一个典型的 0-1 背包问题的变体: 问题描述: 有一个容量为 1.44MB(1474560字节)的软盘 每个块大小为 512 字节 需要在有限容量内存储最大的文件字节总和 关键点: 文件大小以字节为单位 存储空间以块为单位 即使文件不足一个块,也要占用整个块的空间 动态规划解析: 状态定义:dp[i] 表示使用 i 个块时能存储的最大字节数 状态转移:对每个文件,可以选择放入或不放入 约束条件:总块数不能超过软盘容量 时间复杂度:O(n maxSize),其中: n 是文件数量 maxSize 是软盘最大块数(约2880块) 发布于:2025-04-11 16:39 正整数到excel编号之间的转换(对num先进行取余操作,取余之后的值就是字母a往后的偏移量,letter=String.fromCharCode('a'.charCodeAt(0)+remain),将这个字母放到结果队首,然后对num进行整除,循环直到num为0) 发布于:2025-04-10 17:46 最少交换次数(滑动窗口:先算出整个数组内<k的个数,作为窗口大小,然后再算出0-window内>=k的个数,作为res的初始值,然后滑动窗口,当arr[left]>=k时,res--,当arr[right]>=k时,res++) 发布于:2025-04-10 17:40 TLV解析 Ⅱ(字符串操作) 发布于:2025-04-10 16:24 最少有多少个小朋友了(相同的数字的个数/(相同个数+1)*(相同个数+1)) 发布于:2025-04-10 15:11 硬件产品销售方案(回溯 backtrack(path,val,sum)=>) 发布于:2025-04-09 18:40 猴子爬山(动态规划:状态转义方程dp[i]=dp[i-1]+dp[i-3]) 发布于:2025-04-09 18:14 检测工具代码 发布于:2025-04-09 18:03 检查是否存在满足条件的数字组合)(双指针,然后多重判断) 发布于:2025-04-09 17:45 阿里巴巴找黄金宝箱III(遍历数组,用map储存arr[i]上一次出现的下标,如果当前下标位置i-map.get(i)<=k,直接输出left) 发布于:2025-04-09 17:07 阿里巴巴找黄金宝箱II(数组排序,每次都找最大的减) 发布于:2025-04-09 16:48 全量和已占用字符集(字符串操作) 发布于:2025-04-09 16:34 微服务的集成测试(dfs:当扫描到第i行的第i个元素为1时,就递归dfs,sum+=Math.max(max,dfs(j))) 发布于:2025-04-09 16:25 经典屏保问题(判断是否反向:右下角坐标值为(x+50,y+25),当右下角撞到下面或者右边的墙时,就将x轴/y轴的移动方向反向,左上角同理。) 发布于:2025-04-08 18:37 阿里巴巴找黄金宝箱(I)(左右数组的和,如果左右数组的和相等,就输出) 发布于:2025-04-08 16:57 告警抑制(Map) 发布于:2025-04-08 16:35 过滤组合字符串(全排列:回溯) 发布于:2025-04-03 18:56 分糖果(判断是否为偶数,如果为偶数,操作次数+1,n=n/2;如果为奇数,判断(n+1)/2是否为偶数,如果是偶数,n=n+1,res++,否则n=n-1,res++) 发布于:2025-04-03 18:24 查找接口成功率最优时间段(用前缀和求出[left,right]区间的和,然后求平均值,和输入值比较,如果<=平均值,就移动右指针,如果>平均值,说明当前位置有一个当前最大的区间,比较这个区间是否为最大,如果不是则继续,如果是最大,则更新res结果;如果和当前的i最大值一样,那就将两个都放入到res中。最后,如果left和right不相等,说明最后一个窗口没处理完成,需要单独处理) 发布于:2025-04-03 18:15 游戏分组(dfs // 深度优先搜索函数 // 参数说明: // idx: 当前考虑的数组索引 // level: 当前已选择的数字个数 // subSum: 当前已选择数字的和 // totalSum: 整个数组的总和) 发布于:2025-04-03 17:18 新学校选址(找到一个数组排序后的中位数,如果是基数就是这个数,如果是偶数就是这个数的前一个数) 发布于:2025-04-03 16:38 绘图机器(从(0,0)到第一个点时,是先走横坐标,再走纵坐标,所以第一个点的面积应该为0) 发布于:2025-04-02 19:14 素数之积(判断是否为素数的函数:function isPrime(n) { if (n < 2) return false; for (let i = 2; i <= Math.sqrt(n); i++) { if (n % i === 0) return false; } return true; } 发布于:2025-04-02 17:43 考勤信息(滑动窗口统计七天之内的考勤状况) 发布于:2025-04-02 17:27 打印机队列(简单的数组模拟) 发布于:2025-04-02 16:29 JS AES128加解密 发布于:2025-04-03 15:28 找出重复代码】(二维动态规划:定义二维数组dp,初始值设为0,循环两个字符串,如果str1[i]=str2[j],dp[i+1][j+1]==dp[i][j]+1;使用maxLength定义当前最大的公共子串长度,如果dp[i+1][j+1]>maxLength,记录maxLength和当前结束位置i+1。循环后,根据maxLength和结束位置p,确定silce的范围 发布于:2025-04-01 19:24 【二叉树中序遍历】(用栈将二叉树的结构处理出来。然后中序遍历) 发布于:2025-04-01 19:08 【最小调整顺序次数】(模拟队列操作:当插入操作为头操作时,如果数组不为空,就不是排序状态。尾插入不影响;当移除元素时,如果当前队列是有序的 ,就不需要操作,否则就需要操作,ans++) 发布于:2025-04-01 18:29 二元组个数】(用map存储第一个数组中出现的元素及个数,然后遍历第二个数组,如果遇到map中的元素,ans+=map.get()) 发布于:2025-04-01 18:02 【文件目录大小】(递归:先读取每个文件的信息,解析每行输入的三个部分:id,size,child并将处理过后的放入files中,files:{id,size,child}。然后递归计算目标目录的大小:自定义一个递归函数 getSize,将目标目录设为root节点,向下递归子文件夹,如果有子文件夹就递归计算所有子节点的大小并累加,最后返回结果) 发布于:2025-04-01 17:49 华为OD机试真题 Python 实现【水库蓄水问题】(变体接雨水问题,用双指针遍历数组,然后将子数组内的每一个数字能接到的雨水相加(如果当前位置数字 小于左右边界的最小值,能够接水),如果有多个位置接的雨水相同,保留right-left最小的) 发布于:2025-04-01 17:23 找出两个整数数组中同时出现的整数】(用map存储第一个数组中的元素,然后再循环第二个数组,当遇到map中有的数字时,记录下这个数字。再创建新的Map,按出现次数分组存储数字// 获取当前数字及其在第一个数组中的出现次数// 将数字添加到对应次数的组中,并保持组内数字有序;// 获取所有出现次数并按升序排序// 按格式输出结果) 发布于:2025-04-01 16:47 模拟消息队列(两个数组,一个用来存消息,一个用来存接受者,接受者的中包括订阅时间取消时间和能接收到的消息,正序循环message数组,在逆序循环接受者数组,每当有发送消息的时间在订阅和取关之间时,把这个消息放到消息队列中) 发布于:2025-04-01 16:22 【投篮大赛】(简单字符串操作) 发布于:2025-04-01 16:05 【数值同化】(广度优先搜索,搜索能够到达的所有格子,然后遍历矩阵找出无法到达的地区) 发布于:2025-04-01 15:29 数字加减游戏(数学问题:先判断目标-初始是否能被b整除,如果能直接输出0.如果不能就每次判断初始值+a*x或初始值-a*x是否能整除b,如果能,就时最优解) 发布于:2025-04-01 15:10 数组二叉树(// 遍历树中的所有节点,寻找最小的叶子节点 // 判断当前节点是否为叶子节点,需满足以下条件: // 1. 节点值不为 -1(不是空节点) // 2. 节点值小于当前找到的最小叶子值 // 3. 左子节点不存在(超出数组范围或为-1) // 4. 右子节点不存在(超出数组范围或为-1) // 更新最小叶子节点的索引和值,找到叶子节点后,根据叶子节点不断向上推导出父节点,直到找到根节点。对于索引i,其父节点索引为 floor((i-1)/2)) 发布于:2025-04-01 14:56 【招聘】计算至少需要的面试官数量( // 核心算法思路: // 1. 首先对所有面试时间区间按开始时间排序 // 2. 检查相邻区间是否存在时间重叠 // 3. 对于重叠的区间,需要额外的面试官 // 4. 最后根据重叠情况和每个面试官的面试次数限制(m)计算所需面试官总数) 发布于:2025-03-31 18:44 查找一个有向网络的头节点和尾节点(读取输入数据并解析 统计每个节点的入度和出度 使用Map存储节点的入度和出度 每处理一条边,同时更新起点和终点的度数 入度为0的节点是起点 出度为0的节点是终点 终点需要降序排序 检查是否存在起点和终点 收集所有起点和终点 对终点进行排序 输出结果) 发布于:2025-03-31 17:51 [更多]
显示目录

子进程



学习嵌入式的绝佳套件,esp8266开源小电视成品,比自己去买开发板+屏幕还要便宜,省去了焊接不当搞坏的风险。 蜂鸣版+触控升级仅36元,更强的硬件、价格全网最低。

点击购买 固件广场

子进程

Node.js是基于单线程模型架构的,它能够拥有高效的CPU利用率,却限制了多个核心CPU的使用,为此,Node.js提供了child_process 模块以通过多线程来实现对多核CPU的使用。

稳定性: 3 - 稳定

Node通过child_process模块提供了popen(3)数据流。

它能在非阻塞的方式中,通过stdin,stdoutstderr传递数据。

请注意:某些程序使用内部线性缓冲I/O, 它并不妨碍node.js,只是你发送给子进程的数据不会被立即取消。

你可以使用require('child_process').spawn()require('child_process').fork()创建一个子进程。这两种方法有区别,在下文中将进行解释。

开发过程中查看synchronous counterparts效率会更高。

类: ChildProcess

ChildProcess是一个EventEmitter

子进程有三个相关的流child.stdin,child.stdoutchild.stderr。他们可能和会父进程的stdiostreams共享,也可作为独立的对象。

不能直接调用ChildProcess类,使用spawn(),exec(),execFile()fork()方法来创建子进程的实例。

事件: 'error'

  • err {Error Object}错误。

发生于:

  1. 无法创建进程。
  2. 无法杀死进程。
  3. 无论什么原因导致给子进程发送消息失败。

注意:exit事件有可能在错误发生后调用,也可能不调用,所以如果你监听这两个事件来触发函数,记得预防函数会被调用2次。

参考ChildProcess#kill()ChildProcess#send()

事件: 'exit'

  • code {Number} 退出代码, 正常退出时才有效。
  • signal {String} 如果是被父进程杀死,则它为传递给子进程的信号

子进程结束的时候触发这个事件。如果子进程正常终止,则code为最终的退出代码,否则为null。如果是由signal引起的终止,则signal为字符串,否则为 null

注意:子进程的stdio流可能仍为开启模式。

注意,node为'SIGINT''SIGTERM' 建立句柄,所以当信号来临的时候,他们不会终止而是退出。

参靠waitpid(2)

事件: 'close'

  • code{Number} 退出代码, 正常退出时才有效。
  • signal{String} 如果是被父进程杀死,则它为传递给子进程的信号。

子进程里所有stdio流都关闭时触发这个事件。要和'exit'区分开,因为多进程可以共享一个stdio流。

Event: 'disconnect'

父进程或子进程中调用.disconnect()方法后触发这个事件。断开后不会在互发消息,并且.connected属性值为false。

Event: 'message'

  • message{Object} 一个解析过的JSON对象,或者一个原始值。
  • sendHandle{Handle object} 一个Socket或Server对象

通过.send(message, [sendHandle])传递消息。

child.stdin

  • {Stream object}

子进程的stdinWritable Stream(可写流)。如果子进程在等待输入,它就会暂停直到通过调用end()来关闭。

child.stdinchild.stdio[0]的缩写。这两个都指向同一个对象,或者null。

child.stdout

  • {Stream object}

子进程的stdoutReadable Stream(可读流)。

child.stdoutchild.stdio[1]的缩写。 这两个都指向同一个对象,或者null。

child.stderr

  • {Stream object}

子进程的stderrReadable Stream(可写流)。

child.stderrchild.stdio[2]缩写。这两个都指向同一个对象,或者null。

child.stdio

  • {Array}

子进程的管道数组和spawnstdio里设置为'pipe' 的内容次序相对应。

注意,流[0-2]也能分别用ChildProcess.stdin、ChildProcess.stdout和ChildProcess.stderrNote来表示。

在下面的例子里,只有子进程的fd1设置为pipe管道,所以父进程的child.stdio[1]是流(stream),数组里其他值为null

child = child_process.spawn("ls", {
    stdio: [
      0, // use parents stdin for child
      'pipe', // pipe child's stdout to parent
      fs.openSync("err.out", "w") // direct child's stderr to a file
    ]
});

assert.equal(child.stdio[0], null);
assert.equal(child.stdio[0], child.stdin);

assert(child.stdout);
assert.equal(child.stdio[1], child.stdout);

assert.equal(child.stdio[2], null);
assert.equal(child.stdio[2], child.stderr);

child.pid

  • {Integer}

子进程的PID。

例子:

var spawn = require('child_process').spawn,
    grep  = spawn('grep', ['ssh']);

console.log('Spawned child pid: ' + grep.pid);
grep.stdin.end();

child.connected

  • {Boolean} 调用`.disconnect'后设置为false

如果.connected为 false,消息不再可用。

child.kill([signal])

  • signal{String}

发送信号给子进程。如果没有参数,会发送'SIGTERM',参见signal(7)里的可用的信号列表。

var spawn = require('child_process').spawn,
    grep  = spawn('grep', ['ssh']);

grep.on('close', function (code, signal) {
  console.log('child process terminated due to receipt of signal '+signal);
});

// send SIGHUP to process
grep.kill('SIGHUP');

当信号无法传递的时候会触发'error'事件。给已经终止的进程发送信号不会触发'error'事件,但是可以能引起不可预知的后果: 因为有可能PID (进程ID) 已经重新分配给其他进程,信号就会被发送到新的进程里,无法想象这样会引发什么样的事情。

注意:当函数调用kill信号的时候,它实际并并不会杀死进程,只是发送信号给进程。

参见kill(2)

child.send(message[, sendHandle])

  • message{Object}
  • sendHandle{Handle object}

使用child_process.fork()的时候,你能用child.send(message, [sendHandle])给子进程写数据,子进程通过'message'接收消息。

例如:

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

子进程的代码'sub.js' :

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

子进程代码里的process对象拥有send()方法,当它通过信道接收到信息时会触发,并返回对象。

注意:父进程和子进程send()是同步的,不要用来发送大块的数据(可以用管道来代替,参见child_process.spawn)。

不过发送{cmd: 'NODE_foo'}消息是特殊情况。所有包含NODE_前缀的消息都不会被触发,因为它们是node的内部的核心消息,它们会在internalMessage事件里触发,尽量避免使用这个特性。

child.send()里的sendHandle属性用来发送TCP服务或socket对象给其他的进程,子进程会用接收到的对象作为message事件的第二个参数。

如果不能发出消息会触发'error'事件,比如子进程已经退出。

例子: 发送 server 对象

以下是例子:

var child = require('child_process').fork('child.js');

// Open up the server object and send the handle.
var server = require('net').createServer();
server.on('connection', function (socket) {
  socket.end('handled by parent');
});
server.listen(1337, function() {
  child.send('server', server);
});

子进程将会收到这个server对象:

process.on('message', function(m, server) {
  if (m === 'server') {
    server.on('connection', function (socket) {
      socket.end('handled by child');
    });
  }
});

注意,现在父子进程共享了server,某些连接会被父进程处理,某些会被子进程处理。

dgram服务器,工作流程是一样的,监听的是message事件,而不是connection,使用server.bind而不是server.listen。(目前仅支持UNIX平台)

例子: 发送 socket 对象

以下是发送socket对象的例子。他将会创建2个子线程,并且同时处理连接,一个将远程地址74.125.127.100当做VIP发送到一个特殊的子进程,另外一个发送到正常进程。var normal=require('child_process').fork('child.js', ['normal']);var special = require('child_process').fork('child.js', ['special']);

// Open up the server and send sockets to child
var server = require('net').createServer();
server.on('connection', function (socket) {

  // if this is a VIP
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // just the usual dudes
  normal.send('socket', socket);
});
server.listen(1337);

child.js代码如下:

process.on('message', function(m, socket) {
  if (m === 'socket') {
    socket.end('You were handled as a ' + process.argv[2] + ' person');
  }
});

注意,当socket发送给子进程后,如果这个socket被销毁,父进程不再跟踪它,相应的.connections属性会变为null。这种情况下,不建议使用 .maxConnections

child.disconnect()

关闭父子进程间的所有IPC通道,能让子进程优雅的退出。调用这个方法后,父子进程里的.connected标志会变为false,之后不能再发送消息。

当进程里没有消息需要处理的时候,会触发'disconnect'事件。

注意,在子进程还有IPC通道的情况下(如fork()),也可以调用process.disconnect()来关闭它。

创建异步处理

这些方法遵从常用的异步处理模式(比如回调,或者返回一个事件处理)。

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

  • command {String} 要运行的命令
  • args {Array} 字符串参数表
  • options {Object}
    • cwd {String} 子进程的工作目录
    • env {Object} 环境
    • stdio {Array|String} 子进程的stdio配置。
    • customFds {Array} Deprecated 作为子进程stdio使用的文件标示符。
    • detached {Boolean} 子进程将会变成一个进程组的领导者。
    • uid {Number} 设置用户进程的ID。(参见setuid(2))
    • gid {Number} 设置进程组的ID。(参见 setgid(2))
  • 返回: {ChildProcess object}

用指定的command发布一个子进程,args是命令行参数。如果忽略,args是空数组。

第三个参数用来指定附加设置,默认值:

{ cwd: undefined,
  env: process.env
}

创建的子进程里使用cwd指定工作目录,如果没有指定,默认继承自当前的工作目录。

使用env来指定新进程可见的环境变量。默认是process.env

例如,运行ls -lh /usr,获取stdout,stderr和退出代码:

var spawn = require('child_process').spawn,
    ls    = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

ls.on('close', function (code) {
  console.log('child process exited with code ' + code);
});

例如:通过一个非常精巧的方法执行'ps ax | grep ssh'

var spawn = require('child_process').spawn,
    ps    = spawn('ps', ['ax']),
    grep  = spawn('grep', ['ssh']);

ps.stdout.on('data', function (data) {
  grep.stdin.write(data);
});

ps.stderr.on('data', function (data) {
  console.log('ps stderr: ' + data);
});

ps.on('close', function (code) {
  if (code !== 0) {
    console.log('ps process exited with code ' + code);
  }
  grep.stdin.end();
});

grep.stdout.on('data', function (data) {
  console.log('' + data);
});

grep.stderr.on('data', function (data) {
  console.log('grep stderr: ' + data);
});

grep.on('close', function (code) {
  if (code !== 0) {
    console.log('grep process exited with code ' + code);
  }
});

options.stdio

stdio可能是以下几个参数之一:

  • 'pipe'-['pipe', 'pipe', 'pipe'],默认值
  • 'ignore'-['ignore', 'ignore', 'ignore']
  • 'inherit'-[process.stdin, process.stdout, process.stderr][0,1,2]

child_process.spawn()里的'stdio'参数是一个数组,它和子进程的fd相对应,它的值如下:

  1. 'pipe'- 创建在父进程和子进程间的pipe。管道的父进程端以child_process的属性形式暴露给父进程,例如ChildProcess.stdio[fd]。为fds 0 - 2创建的管道也可以通过ChildProcess.stdin,ChildProcess.stdout和ChildProcess.stderr来独立的访问。

  2. 'ipc'- 在父进程和子进程间创建一个IPC通道来传递消息/文件描述符。一个子进程最多有1个IPC stdio文件标识。设置这个选项会激活ChildProcess.send() 方法。如果子进程向此文件标识写入JSON消息,则会触发ChildProcess.on('message') 。如果子进程是Node.js程序,那么IPC通道会激活process.send()和 process.on('message')。

  3. 'ignore'- 在子进程里不要设置这个文件标识,需要注意,Node总会为其spawn的进程打开fd 0-2。如果任何一个被ignored,node将会打开/dev/null并赋给子进程的fd。

  4. Stream对象 - 共享一个tty、file、socket或刷(pipe)可读或可写流给子进程。该流底层(underlying)的文件标识在子进程中被复制给stdio数组索引对应的文件标识(fd)。

  5. 正数 - 这个整数被理解为一个在父进程中打开的文件标识,它和子进程共享,就和共享Stream对象类似。

  6. null,undefined- 使用默认值。 对于stdio fds 0、1 and 2 (换句话说,stdin、stdout或者stderr) ,pipe管道被建立。 对于fd 3及之后,默认是 'ignore'

例如:

var spawn = require('child_process').spawn;

// Child will use parent's stdios
spawn('prg', [], { stdio: 'inherit' });

// Spawn child sharing only stderr
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// Open an extra fd=4, to interact with programs present a
// startd-style interface.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });

options.detached

如果设置了detached选项,子进程将会被作为新进程组的leader,这使得子进程可以在父进程退出后继续运行。

缺省情况下父进程会等detached的子进程退出。要阻止父进程等待一个这样的子进程,调用child.unref()方法,则父进程的事件循环引用计数中将不会包含这个子进程。

detaching一个长期运行的进程,并重新将输出指向文件:

 var fs = require('fs'),
     spawn = require('child_process').spawn,
     out = fs.openSync('./out.log', 'a'),
     err = fs.openSync('./out.log', 'a');

 var child = spawn('prg', [], {
   detached: true,
   stdio: [ 'ignore', out, err ]
 });

 child.unref();

使用detached选项来启动一个长时间运行的进程时,进程不会在后台保持运行,除非他提供了一个不连接到父进程的stdio。如果继承了父进程的stdio,则子进程会继续控制终端。

options.customFds

已废弃,customFds允许指定特定文件描述符作为子进程的stdio。该API无法移植到所有平台,因此被废弃。使用customFds可以将新进程的 [stdin, stdout,stderr] 钩到已有流上;-1表示创建新流。自己承担使用风险。

参见:child_process.exec()child_process.fork()

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

  • command {String} 要执行的命令,空格分割
  • options {Object}
    • cwd {String} 子进程的当前工作目录
    • env {Object} 环境变量
    • encoding {String} (默认: 'utf8')
    • shell {String} 运行命令的shell(默认为: '/bin/sh' UNIX, 'cmd.exe' Windows, 该shell必须接收UNIX上的-c开关 ,或者Windows上的/s /c开关。Windows上,命令解析必须兼容cmd.exe。)
    • timeout {Number} (默认: 0)
    • maxBuffer {Number} (默认: 200*1024)
    • killSignal {String} (默认: 'SIGTERM')
    • uid {Number} 设置进程里的用户标识。 (见 setuid(2)。)
    • gid {Number} 设置进程里的群组标识。(见 setgid(2)。)
  • callback {Function} 进程终止的时候调用
    • error {Error}
    • stdout {Buffer}
    • stderr {Buffer}
  • 返回: ChildProcess对象

在shell里执行命令,并缓冲输出。

var exec = require('child_process').exec,
    child;

child = exec('cat *.js bad_file | wc -l',
  function (error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});

回调参数是(error, stdout, stderr)。如果成功,则,error值为null。 如果失败,则error变为Error的实例,error.code等于子进程退出码,并且 error.signal会被设置为结束进程的信号名。

第二个参数可以设置一些选项。默认如下:

{ encoding: 'utf8',
  timeout: 0,
  maxBuffer: 200*1024,
  killSignal: 'SIGTERM',
  cwd: null,
  env: null }

如果timeout大于0,子进程运行时间超过timeout时会被终止。killSignal(默认: 'SIGTERM')能杀死子进程。maxBuffer设定了stdout或stderr的最大数据量,如果子进程的数量量超过了,将会被杀死。

(file[, args][, options][, callback])

  • file {String} 要运行的程序的文件名
  • args {Array} 参数列表
  • options {Object}
    • cwd {String} 子进程的工作目录
    • env {Object} 环境
    • encoding {String} (默认: 'utf8')
    • timeout {Number} (默认: 0)
    • maxBuffer {Number} (默认: 200*1024)
    • killSignal {String} (默认: 'SIGTERM')
    • uid {Number} 设置进程里的用户标识。 (参见setuid(2)。)
    • gid {Number} 设置进程里的群组标识。(参见setgid(2)。)
  • callback {Function} 进程终止的时候调用
    • error {Error}
    • stdout {Buffer}
    • stderr {Buffer}
  • 返回: ChildProcess对象

child_process.exec()类似,不同之处在于这是执行一个指定的文件,因此它比child_process.exec精简些,参数相同。

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

  • modulePath {String} 子进程里运行的模块
  • args {Array} 参数列表
  • options {Object}
    • cwd {String} 子进程的工作目录
    • env {Object} 环境
    • execPath {String} 执行文件路径
    • execArgv {Array} 执行参数(默认: process.execArgv)
    • silent {Boolean} 如果是 true ,子进程将会用父进程的 stdin, stdout, and stderr ,否则,将会继承自父进程, 更多细节,参见 spawn()stdio 参数里的 "pipe" 和 "inherit" 选项(默认 false)
    • uid {Number} 设置进程里的用户标识。 (见 setuid(2)。)
    • gid {Number} 设置进程里的群组标识。 (见 setgid(2)。)
  • 返回: ChildProcess对象

这是spawn()的特殊例子,用于派生Node进程。除了拥有子进程的所有方法,它的返回对象还拥有内置通讯通道。参见child.send(message, [sendHandle])

这些Nodes是全新的V8实例化,假设每个Node最少需要30ms的启动时间,10mb的存储空间,可想而知,创建几千个Node是不太现实的。

options对象中的execPath属性可以用于执行文件(非当前node )创建子进程。这需要小心使用,缺省情况下fd表示子进程的NODE_CHANNEL_FD环境变量。该fa的输入和输出是以行分割的JSON对象。

创建同步进程

以下这些方法是同步的,意味着他会阻塞事件循环,并暂停执行代码,直到spawned的进程退出。

同步方法简化了任务进程,比如大为简化在应用初始化加载/处理过程。

child_process.spawnSync(command[, args][, options])

  • command {String} 要执行的命令
  • args {Array} 参数列表
  • options {Object}
    • cwd {String} 子进程的当前工作目录
    • input {String|Buffer} 传递给spawned进程的值,这个值将会重写stdio[0]
    • stdio {Array} 子进程的stdio配置。
    • env {Object} 环境变量
    • uid {Number} 设置用户进程的ID。 (参见setuid(2)。)
    • gid {Number} 设置进程组的ID。 (参见setgid(2)。)
    • timeout {Number} 子进程运行最大毫秒数。 (默认: undefined)
    • killSignal {String} 用来终止子进程的信号。 (默认: 'SIGTERM')
    • maxBuffer {Number}
    • encoding {String} stdio输入和输出的编码方式。 (默认: 'buffer')
  • 返回: {Object}
    • pid {Number} 子进程的pid
    • output {Array} stdio输出的结果数组
    • stdout {Buffer|String} output[1]的内容
    • stderr {Buffer|String} output[2]的内容
    • status {Number} 子进程的退出代码
    • signal {String} 用来杀死子进程的信号
    • error {Error} 子进程错误或超时的错误代码

spawnSync直到子进程关闭才会返回。超时或者收到killSignal信号,也不会返回,直到进程完全退出。进程处理完SIGTERM信号后并不会结束,直到子进程完全退出。

child_process.execFileSync(command[, args][, options])

  • command {String} 要执行的命令
  • args {Array} 参数列表
  • options {Object}
    • cwd {String} 子进程的当前工作目录
    • input {String|Buffer}传递给spawned进程的值,这个值将会重写 stdio[0]
    • stdio {Array}子进程的stdio配置。 (默认: 'pipe')
      • stderr 默认情况下会输出给父进程的' stderr除非指定了 stdio
    • env {Object} 环境变量
    • uid {Number} 设置用户进程的ID。 (参见setuid(2)。)
    • gid {Number} 设置进程组的ID。 (参见setgid(2)。)
    • timeout {Number} 进程运行最大毫秒数。 (默认: undefined)
    • killSignal {String} 用来终止子进程的信号。 (默认: 'SIGTERM')
    • maxBuffer {Number}
    • encoding {String} stdio输入和输出的编码方式。 (默认: 'buffer')
  • 返回: {Buffer|String} 来自命令的stdout

直到子进程完全退出,execFileSync才会返回。超时或者收到killSignal信号,也不会返回,直到进程完全退出。进程处理完SIGTERM信号后并不会结束,直到子进程完全退出。

如果进程超时,或者非正常退出,这个方法将会抛出异常。Error会包含整个child_process.spawnSync结果。

child_process.execSync(command[, options])

  • command {String} 要执行的命令
  • options {Object}
    • cwd {String} 子进程的当前工作目录
    • input {String|Buffer} 传递给spawned进程的值,这个值将会重写stdio[0]
    • stdio {Array} 子进程的stdio配置。 (默认: 'pipe')
      • stderr 默认情况下会输出给父进程的' stderr 除非指定了stdio
    • env {Object} 环境变量
    • uid {Number} 设置用户进程的ID。 (参见setuid(2)。)
    • gid {Number} 设置进程组的ID。 (参见setgid(2)。)
    • timeout {Number} 进程运行最大毫秒数。 (默认: undefined)
    • killSignal {String} 用来终止子进程的信号。 (默认: 'SIGTERM')
    • maxBuffer {Number}
    • encoding {String} stdio输入和输出的编码方式。 (默认: 'buffer')
  • 返回: {Buffer|String}来自命令的stdout

直到子进程完全退出,execSync才会返回。超时或者收到killSignal信号,也不会返回,直到进程完全退出。进程处理完SIGTERM信号后并不会结束,直到子进程完全退出。

如果进程超时,或者非正常退出,这个方法将会抛出异常。Error会包含整个child_process.spawnSync结果。

以上就是Node.js官方文档中有关子进程的介绍。

由JSRUN为你提供的JS在线运行、在线编译工具
        JSRUN提供的JS 在线运行,JS 在线运行工具,基于linux操作系统环境提供线上编译和线上运行,具有运行快速,运行结果与常用开发、生产环境保持一致的特点。
yout