child_process中spawn和exec方法的使用

2019-01-29 14:33:07

child_process是nw.exe的一个内置模块,通过它可以实现创建多线程,并可实现主线程和子线程之间的通信。child_process模块中主要使用有两个方法spawn和exec,这两个方法都可以用来创建子线程。除了spawn和exec外,child_process模块还有execFile,fork,spawnSync,execFileSync,execSync,它们都是基于spawn的不同封装。


使用child_process模块模块不外乎几种情况:1.调用系统命令行 2.打开第三方软件 3.打开第三方软件并实现通信。


(一)child_process模块 Demo


var cp = require('child_process'); //子进程

var result = "";

 

cp.exec("ipconfig", function(error, stdout, stderr) {

console.log("error", error);

console.log("stdout", stdout);

console.log("stderr", stderr);

});

 

result = cp.spawn('cmd.exe', ['/s', '/c', 'ipconfig']);

result.on('close', function(code) {

console.log('child process exited with code :' + code);

});

result.stdout.on('data', function(data) {

console.log('stdout: ' + data);

});

result.stderr.on('data', function(data) {

console.log('stderr: ' + data);

});


以上两个方法无论是spawn还是exec都通过调用了命令行ipconfig获取系统相关IP信息,两者得到的结果是一样的,本Demo可看出只不过两种调用的写法不一样而已。



(二)spawn和exec的区别

(1)两者实现的写法不同,参照上述Demo即可了解。


(2)spawn在执行时会返回一个stdout和stderr流对象,为边执行边返回。exec是在执行完成后返回一个完整的buffer,这个buffer的大小应该是200k。如果子进程返回的数据大小超过了200k,程序将会崩溃,同时显示错误信息"Error:maxBuffer exceeded"。


(3)spawn在执行完成后会抛出close事件监听,并返回状态码,通过状态码可以知道子进程是否顺利执行。exec只能通过返回的buffer去识别完成状态,识别起来较为麻烦。


上述(一)中已经介绍如何调用系统命令行,下面为打开第三方软件的例子,如使用exec打开QQ程序:



var cp = require('child_process'); //子进程

var path = "";//第三方根目录

cp.exec(path + "\\QQ.exe", function(error, stdout, stderr) {

console.log("error", error);

console.log("stdout", stdout);

console.log("stderr", stderr);

});


打开第三方软件并通信,如使用spawn,调用ffmpeg进行转码:


var cp = require('child_process'); //子进程

var path = ""; //第三方根目录

result = cp.spawn(path + "\\ffmpeg.exe", ['-y', '-i', "1.mpg", '1.mp4']);

result.on('close', function(code) {

console.log('child process exited with code :' + code);

});

result.stdout.on('data', function(data) {

console.log('stdout: ' + data);

});

result.stderr.on('data', function(data) {

console.log('stderr: ' + data);

});


综上所述,能使用spawn实现子进程的尽量使用spawn,其一可以避免不必要的异常错误,其次在调用上较为规范。如果需要通过child_process模块反复调用某个第三方软件或程序,注意一点就是避免重复打开(如子进程进入死循环,或者子进程没结束就又重复打开),过多的子进程会消耗系统的资源,严重时可能会造成卡顿,死机等情况。如果遇到这种情况,可以通过.kill();方法停止线程运行。如上述使用spawn的例子中均有一个result,停止线程方法为:


result.kill();


如需强制关闭,如强制关闭ffmpeg.exe进程,可用:


function killFFmpeg() {

cp.exec('tasklist | find "ffmpeg.exe"', function(error, stdout, stderr) {

if(stdout != "") {

cp.exec("taskkill /f /t /im ffmpeg.exe", function(error, stdout, stderr) {});

}

});

};


  • 2018-12-07 22:55:02

    nginx worker_processes 配置

    据另一种说法是,nginx开启太多的进程,会影响主进程调度,所以占用的cpu会增高, 这个说法我个人没有证实,估计他们是开了一两百个进程来对比的吧。

  • 2018-12-08 11:44:26

    php 时间函数strtotime 使用详解

    这篇文章介绍的内容是关于php 时间函数strtotime 使用详解 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

  • 2018-12-09 15:52:37

    【Android - 进阶】之Animator属性动画

    在3.0系统之前,Android给我们提供了逐帧动画Frame Animation和补间动画Tween Animation两种动画: 逐帧动画的原理很简单,就是将一个完整的动画拆分成一张张单独的图片,然后将它们连贯起来进行播放; 补间动画是专门为View提供的动画,可以实现View的透明度、缩放、平移和旋转四种效果。

  • 2018-12-09 18:12:45

    显示软键盘,并让布局压缩

    博客 学院 下载 图文课 论坛 APP 问答 商城 VIP会员 活动 招聘 ITeye GitChat 搜博主文章 写博客传资源 原

  • 2018-12-09 22:48:14

    ToolBar修改返回按钮图标

    使用Toolbar时,有时因为不同的手机设备,不能使用系统默认的主题样式或者图标,必须指定特定的资源,防止APP在不同设备上的效果不一样! 我在使用Toolbar时,把这个布局作为一个公共的了,所以修改起来比较容易,下面是该Toolbar的布局文件:

  • 2018-12-09 22:49:12

    Android 修改Toolbar自带的图标颜色

    toolbar自带的按钮颜色是黑色,现在想修改按钮图标颜色,方法如下: 在布局文件中的Toolbar中增加如下2个 属性