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) {});

}

});

};


  • 2019-07-24 01:21:15

    android开发无障碍app

    最近做一些为盲人提供服务的APP,还是挺有感触的,感谢手机和互联网的普及,他们的生活比以前丰富了很多。 通过读屏软件,盲人可以操作手机,上网浏览信息。读屏软件的工作原理很简单,就是读出屏幕上按钮、文本的信息。

  • 2019-07-26 19:31:03

    Guacamole搭建

    因项目需要,经历多天查阅各种文档,几经波折终于功德圆满,写下此篇文章供大家分享。Guacamole就个人理解而言是一个可以通过web浏览器访问远程服务器终端进行操作的可视化工具。主要由web(浏览器)、Guacamole Server(核心)、Remote Desktops(远程桌面)三大模块组成。

  • 2019-07-30 22:36:10

    使用 Spring Initializr 初始化 Spring Boot 项目

    万事开头难,你需要设置一个目录结构存放各种项目内容,创建构建文件,并在其中加入各 种依赖。Spring Boot CLI消除了不少设置工作,但如果你更倾向于传统Java项目结构,那你应该 看看Spring Initializr。

  • 2019-08-06 15:30:08

    小程序展示富文本

    然而rich-text有个问题,它不能够给内联img设置宽度100%,这样图片就容易溢出屏幕。我们只能在后台返回富文本的时候对图片的img标签进行格式化。或者前端进行格式化也行,我赞成使用后端,因为很多种情况我们不一定都能想得到。

  • 2019-08-07 09:07:32

    最全的Service Worker讲解

    Service Worker 最主要的特点是:在页面中注册并安装成功后,运行于浏览器后台,不受页面刷新的影响,可以监听和截拦作用域范围内所有页面的 HTTP 请求。 基于 Service Worker API 的特性,结合 Fetch API、Cache API、Push API、postMessage API 和 Notification API,可以在基于浏览器的 web 应用中实现如离线缓存、消息推送、静默更新等 native 应用常见的功能,以给 web 应用提供更好更丰富的使用体验。

  • 2019-08-07 09:09:19

    windows系统下定时关闭程序

    其中xxx.exe是你要关闭的进程中运行的exe,可以ctrl+alt+del打开任务管理器,进到详细信息查看 然后把.txt文件后缀改成.bat(此时要在查看一栏勾上文件拓展名,要不还是txt文档)