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-09-03 23:09:17

    Linux下静态库(.a)和动态库(.so) 的生成与使用以及区别

    静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

  • 2019-09-03 23:19:12

    ./configure 的配置和用法

    Linux环境下的软件安装,并不是一件容易的事情;如果通过源代码编译后在安装,当然事情就更为复杂一些;现在安装各种软件的教程都非常普遍;但万变不离其中,对基础知识的扎实掌握,安装各种软件的问题就迎刃而解了。Configure脚本配置工具就是基础之一,它是autoconf的工具的基本应用。

  • 2019-09-04 16:24:17

    Ubuntu apt-get更换为阿里源

    ​进入阿里巴巴开源镜像页面,找到ubuntu,点击后面的帮助,可以看到类似下面的介绍,加入就好。切记下面的第三步。

  • 2019-09-04 16:32:56

    Ubuntu tar 解压缩命令详解

    tar 解压缩命令详解,这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。