您的位置:首页 > Web前端 > Node.js

[朝花夕拾]关于nodejs中child_process之中spawn和exec的区别

2016-06-14 23:57 645 查看
近日整理以前的node项目时发现一个文件同时声明了spawn和exec两种方法。最后只是用了spawn方法,所以查了一下这两者的区别。

Nodejs基于事件驱动来处理并发,本身是单线程模式运行的。Nodejs通过使用child_process模块来生成多个子进程来处理其他事物。主要包括4个异步进程函数(spawn,exec,execFile,fork)和3个同步进程函数(spawnSync,execFileSync,execSync)。以异步函数中spawn是最基本的创建子进程的函数,其他三个异步函数都是对spawn不同程度的封装。spawn只能运行指定的程序,参数需要在列表中给出,而exec可以直接运行复杂的命令。

比如要运行 du -sh /disk1 命令, 使用spawn函数需要写成spawn(‘du‘, [‘-sh ‘, ‘/disk1’]),而使用exec函数时,可以直接写成exec(‘du -sh /disk1’)。exec是会先进行Shell语法解析,因此用exec函数可以更方便的使用复杂的Shell命令,包括管道、重定向等。

 

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

exec在子进程输出结果将放入buffer中,在结果返回完全之后,再将输出一次性地以回调函数参数的形式返回。如果exec的buffer体积设置的不够大,它将会以一个“maxBuffer exceeded”错误失败告终。另外,exec函数是对spawn的一种友好封装,增加Shell命令解析,可以直接嵌入复杂的命令

a)        语法:child_process.exec(command[, options], callback)

b)        实例:

// 使用wget下载文件的函数

vardownload_file_wget = function(file_url) {

 

  // 提取文件名

  var file_name =url.parse(file_url).pathname.split('/').pop();

  // 组合wget命令

  var wget = 'wget -P ' + DOWNLOAD_DIR + ' ' +file_url;

  // 使用exec执行wget命令

 

  var child = exec(wget, function(err, stdout,stderr) {

    if (err) throw err;

    else console.log(file_name + ' downloadedto ' + DOWNLOAD_DIR);

  });

};

//执行cat统计文件

varchildProcess = require('child_process');

 

var ls =childProcess.exec('cat *.js | wc', function (error, stdout, stderr) {

   if (error) {

     console.log(error.stack);

     console.log('Error code: '+error.code);

   }

   console.log('Child Process STDOUT:'+stdout);

});

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

spawn在子线程开始执行后,就开始不断将数据从子进程返回给主进程。从语法中我们可以发现与exec的一个区别是spawn是不支持callback函数的,它通过流的方式发数据传给主进程,从而实现了多进程之间的数据交换。这个功能的直接用应用场景就是“系统监控”。在Linux下,我们有很多命令行工具,可以实时监控CPU,内存,IO,网络等数据,那么用Node的child_process模块可以很容易地把这些数据采集的我们自己的应用中。

a)        语法:child_process.spawn(command[, args][, options])

b)        实例:

//这个实例就是所做的项目中nodejs实现堡垒机中生成子线程远程登录的方法

Var worker = spawn('telnet', ['202.198.0.123']);

            client.telnet = worker.stdin;

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

                client.fileWriteStream.end();

                //client.status = 2;

                client.socket.write('\n\r');

               client.socket.write('[Common]');

               client.socket.write('[INFO] :Connection to Device has closed!\n\r');

                closeSocket(client.socket,client);

                                      client.socket.destroy();

            });

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

                data = data.toString();

                if(client.status == 3){

                    return;

                }

                if((data.indexOf('nmslogin')>=0)&&(client.isLogin==0)){

                    client.secret = 1;

                    client.telnet.write('username\n');

                }elseif((data.indexOf('Password')>=0)&&(client.isLogin==0)){

                    client.telnet.write('password\n');

                    client.isLogin = 1;

                }elseif(data.indexOf('Password')>=0&& client.status == 4){

                     client.notChange= 1;

                     client.fileWriteStream.write(data);

                    client.socket.write(data);

                    client.datas =client.datas+data.toString();

                            }else {

                    client.fileWriteStream.write(data);

                    client.socket.write(data);

                    client.datas =client.datas+data.toString();

                }

            });

            worker.on('error',function(error){

                client.fileWriteStream.end();

                client.status = 2;

               client.socket.write('[ERR2]  :Anerror occured!')

               client.socket.write('[INFO] :Connection to Device has closed!\n\r');

               //client.socket.write('>>>>Input Device IP:');

                closeSocket(client.socket,client);

            });

 

扩展阅读:

JavaScript 运行机制详解:再谈Event Loop

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

Node.js软肋之回调大坑

http://www.infoq.com/cn/articles/nodejs-callback-hell

Node.js的线程和进程

http://www.admin10000.com/document/4196.html

 

http://rickgaribay.net/archive/2012/01/28/node-is-not-single-threaded.aspx

 

Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结

http://www.360doc.com/content/13/0117/12/5073814_260691714.shtml
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nodejs 异步 线程