1.child_process是Node.js的一個十分重要的模塊,通過它可以實現創建多進程,以利用多核計算資源。
child_process
模塊提供了四個創建子進程的函數,分別是spawn
,exec
,execFile
和fork
。其中spawn
是最原始的創建子進程的函數,其他三個都是對spawn
不同程度的封裝。
spawn
只能運行指定的程序,參數需要在列表中給出,相當於execvp
系統函數,而exec
可以直接運行復雜的命令。
child_process.spawn(command, [args], [options])
child_process.exec(command, [options], callback)
例如要運行ls -lh /usr
,使用spawn
需要寫成spawn('ls', ['-lh', '/usr'])
,而exec
只需exec('ls -lh /usr')
。
exec
的實現原理是啟動了一個系統shell來解析參數,因此可以是非常復雜的命令,包括管道和重定向。
此外,exec
還可以直接接受一個回調函數作為參數,回調函數有三個參數,分別是err
, stdout
, stderr
,非常方便直接使用,例如:
1 require('child_process').exec( 'ls -lh /usr' , function(err, stdout , stderr ) { 2 console.log( stdout ); 3 });
如果使用spawn
,則必須寫成:
2.fork
函數用於直接運行Node.js模塊,例如fork('./child.js')
,相當於spawn('node', ['./child.js'])
。
與默認的spawn
不同的是,fork
會在父進程與子進程直接建立一個IPC管道,用於父子進程之間的通信。例如
1 var n = require('child_process').fork( './child.js'); 2 n. on ( 'message', function(m) { 3 console. log ( 'PARENT got message:', m); 4 }); 5 n.send({ hello: 'world' });
child.js的內容
1 process. on ( 'message', function(m) { 2 console. log ( 'CHILD got message:', m); 3 }); 4 process.send({ foo: 'bar' });
結果:
1 PARENT got message: { foo: 'bar' } 2 CHILD got message: { hello: 'world' }
3.fork
函數有一個問題,就是它只能運行JavaScript代碼,如果你喜歡用CoffeeScript(或者其他任何編譯到js的語言),是無法通過fork
調用的。
一個簡單的方法是把代碼編譯到JavaScript再運行,但是很不方便,有沒有什么辦法呢?答案是可以的,
child_process.spawn(command, [args], [options])
通過把options
參數的stdio
設為['ipc']
,
即可在父子進程之間建立IPC管道。例如子進程使用CoffeeScript:
1 child_process = require ('child_process'); 2 options ={stdio: ['ipc'] }; 3 child = child_process.spawn('coffee', ['./child.coffee'], options);
其中只要把spawn
的第一個參數設置為運行對應腳本的解釋器,即可運行,例如使用Continuation.js,
只需child = child_process.spawn('continuation', ['./child.coffee'], options)
。