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