欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解從Node.js的child_process模塊來學(xué)習(xí)父子進(jìn)程之間的通信

 更新時(shí)間:2017年03月27日 16:53:42   作者:liangklfang  
這篇文章主要介紹了從Node.js的child_process模塊來學(xué)習(xí)父子進(jìn)程之間的通信,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。

child_process模塊提供了和popen(3)一樣的方式來產(chǎn)生自進(jìn)程,這個(gè)功能主要是通過child_process.spawn函數(shù)來提供的:

const spawn = require('child_process').spawn; 
const ls = spawn('ls', ['-lh', '/usr']); 
ls.stdout.on('data', (data) => { 
 console.log(`stdout: ${data}`); 
}); 
ls.stderr.on('data', (data) => { 
 console.log(`stderr: ${data}`); 
}); 
ls.on('close', (code) => { 
 console.log(`child process exited with code $[code]`); 
}); 

默認(rèn)情況下,Node.js進(jìn)程和子進(jìn)程之間的stdin,stdout,stderr管道是已經(jīng)存在的。通常情況下這個(gè)方法可以以一種非阻塞的方式來傳遞數(shù)據(jù)。(注意,有些程序在內(nèi)部使用line-buffered I/O。因?yàn)檫@也不會(huì)影響到Node.js,這意味著傳遞給子進(jìn)程的數(shù)據(jù)可能不會(huì)馬上消費(fèi))。

chid-process的spawn方法是通過一種異步的方式來產(chǎn)生自進(jìn)程的,因此不會(huì)阻塞Node.js的事件循環(huán),然而child-process.spawnSync方法是同步的,他會(huì)阻塞事件循環(huán)只到產(chǎn)生的進(jìn)程退出或者終止。

child_process.exec:產(chǎn)生一個(gè)shell客戶端,然后使用shell來執(zhí)行程序,當(dāng)完成的時(shí)候傳遞給回調(diào)函數(shù)一個(gè)stdout和stderr

child_process.execFile:和exec相似,但是他不會(huì)馬上產(chǎn)生一個(gè)shell

child_process.fork:產(chǎn)生一個(gè)新的Node.js進(jìn)程,同時(shí)執(zhí)行一個(gè)特定的模塊來產(chǎn)生IPC通道,進(jìn)而在父進(jìn)程和子進(jìn)程之間傳輸數(shù)據(jù)

child_process.execSync:和exec不同之處在于會(huì)阻塞Node.js的事件循環(huán),然而child-process

child_process.execFileSync:和execFile不同之處在于會(huì)阻塞Node.js的事件循環(huán),然而child-process在一些特殊情況下,例如自動(dòng)化shell腳本,同步的方法可能更加有用。多數(shù)情況下,同步的方法對性能產(chǎn)生重要的影響,因?yàn)樗麜?huì)阻塞事件循環(huán)

child_process.spawn(), child_process.fork(), child_process.exec(), and child_process.execFile()都是異步的API。每一個(gè)方法都會(huì)產(chǎn)生一個(gè)ChildProcess實(shí)例,而且這個(gè)對象實(shí)現(xiàn)了Node.js的EventEmitter這個(gè)API,于是父進(jìn)程可以注冊函數(shù),在子進(jìn)程的特定事件觸發(fā)的時(shí)候被調(diào)用。 child_process.exec() 和 child_process.execFile()可以指定一個(gè)可選的callback函數(shù),這個(gè)函數(shù)在子進(jìn)程終止的時(shí)候被調(diào)用。

在windows平臺(tái)上執(zhí)行.bat和.cmd:

child_process.exec和child_process.execFile的不同之處可能隨著平臺(tái)不同而有差異。在Unit/Linux/OSX平臺(tái)上execFile更加高效,因?yàn)樗粫?huì)產(chǎn)生shell。在windows上,.bat/.cmd在沒有終端的情況下是無法執(zhí)行的,因此就無法使用execFile(child_process.spawn也無法使用)。在window上,.bat/.cmd可以使用spawn方法,同時(shí)指定一個(gè)shell選項(xiàng);或者使用child_process.exec或者通過產(chǎn)生一個(gè)cmd.exe同時(shí)把.bat/.cmd文件傳遞給它作為參數(shù)(child_process.exec就是這么做的)。

const spawn = require('child_process').spawn; 
const bat = spawn('cmd.exe', ['/c', 'my.bat']);//使用shell方法指定一個(gè)shell選項(xiàng) 
bat.stdout.on('data', (data) => { 
 console.log(data); 
}); 
bat.stderr.on('data', (data) => { 
 console.log(data); 
}); 
 
bat.on('exit', (code) => { 
 console.log(`Child exited with code $[code]`); 
}); 

或者也可以使用如下的方式:

const exec = require('child_process').exec;//產(chǎn)生exec,同時(shí)傳入.bat文件 
exec('my.bat', (err, stdout, stderr) => { 
 if (err) { 
  console.error(err); 
  return; 
 } 
 console.log(stdout); 
}); 

child_process.exec(command[, options][, callback])

其中options中的maxBuffer參數(shù)表示stdout/stderr允許的最大的數(shù)據(jù)量,如果超過了數(shù)據(jù)量那么子進(jìn)程就會(huì)被終止,默認(rèn)是200*1024比特;killSignal默認(rèn)是'SIGTERM'。其中回調(diào)函數(shù)當(dāng)進(jìn)程結(jié)束時(shí)候調(diào)用,參數(shù)分別為error,stdout,stderr。這個(gè)方法返回的是一個(gè)ChildProcess對象。

const exec = require('child_process').exec; 
const child = exec('cat *.js bad_file | wc -l', 
 (error, stdout, stderr) => { 
  console.log(`stdout: ${stdout}`); 
  console.log(`stderr: ${stderr}`); 
  if (error !== null) { 
   console.log(`exec error: ${error}`); 
  } 
}); 

上面的代碼產(chǎn)生一個(gè)shell,然后使用這個(gè)shell執(zhí)行命令,同時(shí)對產(chǎn)生的結(jié)果進(jìn)行緩存。其中回調(diào)函數(shù)中的error.code屬性表示子進(jìn)程的exit code,error.signal表示結(jié)束這個(gè)進(jìn)程的信號,任何非0的代碼表示出現(xiàn)了錯(cuò)誤。默認(rèn)的options參數(shù)值如下:

{ 
 encoding: 'utf8', 
 timeout: 0, 
 maxBuffer: 200*1024,//stdout和stderr允許的最大的比特?cái)?shù)據(jù),超過她子進(jìn)程就會(huì)被終止
 cwd: null, 
 env: null 
} 

如果timeout非0,那么父進(jìn)程就會(huì)發(fā)送信號,這個(gè)信號通過killSignal指定,默認(rèn)是"SIGTERM"來終結(jié)子進(jìn)程,如果子進(jìn)程超過了timeout指定的時(shí)間。注意:和POSIX系統(tǒng)上調(diào)用exec方法不一樣的是,child_process.exec不會(huì)替換當(dāng)前線程,而是使用一個(gè)shell去執(zhí)行命令

child_process.execFile(file[, args][, options][, callback])

其中file表示需要執(zhí)行的文件。 child_process.execFile()和exec很相似,但是這個(gè)方法不會(huì)產(chǎn)生一個(gè)shell。指定的可執(zhí)行文件會(huì)馬上產(chǎn)生一個(gè)新的線程,因此其效率比child_process.exec高。

const execFile = require('child_process').execFile; 
const child = execFile('node', ['--version'], (error, stdout, stderr) => { 
 if (error) { 
  throw error; 
 } 
 console.log(stdout); 
}); 

因?yàn)椴粫?huì)產(chǎn)生shell,一些I/O redirection和file globbing這些行為不支持

child_process.fork(modulePath[, args][, options])

最后,我們來看看子進(jìn)程和父進(jìn)程之間是如何通信的:

服務(wù)器端的代碼:

var http = require('http'); 
var cp = require('child_process'); 
var server = http.createServer(function(req, res) { 
  var child = cp.fork(__dirname + '/cal.js'); 
  //每個(gè)請求都單獨(dú)生成一個(gè)新的子進(jìn)程 
  child.on('message', function(m) { 
    res.end(m.result + '\n'); 
  }); 
  //為其指定message事件 
  var input = parseInt(req.url.substring(1)); 
  //和postMessage很類似,不過這里是通過send方法而不是postMessage方法來完成的 
  child.send({input : input}); 
}); 
server.listen(8000); 

子進(jìn)程的代碼:

function fib(n) { 
  if (n < 2) { 
    return 1; 
  } else { 
    return fib(n - 2) + fib(n - 1); 
  } 
} 
//接受到send傳遞過來的參數(shù) 
process.on('message', function(m) { 
  //console.log(m); 
  //打印{ input: 9 } 
  process.send({result: fib(m.input)}); 
}); 

child_process.spawn(command[, args][, options])

{
 cwd: undefined, //產(chǎn)生這個(gè)進(jìn)程的工作目錄,默認(rèn)繼承當(dāng)前的工作目錄
 env: process.env//這個(gè)參數(shù)用于指定對于新的進(jìn)程可見的環(huán)境變量,默認(rèn)是process.env
}

其中cwd用于指定子進(jìn)程產(chǎn)生的工作目錄,如果沒有指定表示的就是當(dāng)前工作目錄。env用于指定新進(jìn)程的環(huán)境變量,默認(rèn)為process.env。下面的例子展示了使用ls -lh/usr來獲取stdout,stderr以及exit code:

const spawn = require('child_process').spawn; 
const ls = spawn('ls', ['-lh', '/usr']); 
ls.stdout.on('data', (data) => { 
 console.log(`stdout: ${data}`); 
}); 
ls.stderr.on('data', (data) => { 
 console.log(`stderr: ${data}`); 
}); 
ls.on('close', (code) => { 
 console.log(`child process exited with code $[code]`); 
}); 

下面是一個(gè)很詳細(xì)的運(yùn)行"ps ax|grep ssh"的例子:

const spawn = require('child_process').spawn; 
const ps = spawn('ps', ['ax']); 
const grep = spawn('grep', ['ssh']); 
ps.stdout.on('data', (data) => { 
 grep.stdin.write(data); 
}); 
ps.stderr.on('data', (data) => { 
 console.log(`ps stderr: ${data}`); 
}); 
ps.on('close', (code) => { 
 if (code !== 0) { 
  console.log(`ps process exited with code $[code]`); 
 } 
 grep.stdin.end(); 
}); 
grep.stdout.on('data', (data) => { 
 console.log(`${data}`); 
}); 
grep.stderr.on('data', (data) => { 
 console.log(`grep stderr: ${data}`); 
}); 
grep.on('close', (code) => { 
 if (code !== 0) { 
  console.log(`grep process exited with code $[code]`); 
 } 
}); 

用下面的例子來檢查錯(cuò)誤的執(zhí)行程序:

const spawn = require('child_process').spawn; 
const child = spawn('bad_command'); 
child.on('error', (err) => { 
 console.log('Failed to start child process.'); 
}); 

options.detached:

在windows上,把這個(gè)參數(shù)設(shè)置為true的話,這時(shí)候如果父進(jìn)程退出了那么子進(jìn)程還會(huì)繼續(xù)運(yùn)行,而且子進(jìn)程有自己的console window。如果把子進(jìn)程設(shè)置了這個(gè)為true,那么就不能設(shè)置為false了。在非window平臺(tái)上,如果把這個(gè)設(shè)置為true,子進(jìn)程就會(huì)成為進(jìn)程組合和session的leader,這時(shí)候子進(jìn)程在父進(jìn)程退出以后會(huì)繼續(xù)執(zhí)行,不管子進(jìn)程是否detached??梢詤⒁妔etsid(2)。

const fs = require('fs'); 
const spawn = require('child_process').spawn; 
const out = fs.openSync('./out.log', 'a'); 
const err = fs.openSync('./out.log', 'a'); 
const child = spawn('prg', [], { 
 detached: true,//依賴于父進(jìn)程 
 stdio: [ 'ignore', out, err ] 
}); 
child.unref();//允許父進(jìn)程單獨(dú)退出,不用等待子進(jìn)程 

當(dāng)使用了detached選項(xiàng)去產(chǎn)生一個(gè)長期執(zhí)行的進(jìn)程,這時(shí)候如果父進(jìn)程退出了那么子進(jìn)程就不會(huì)繼續(xù)執(zhí)行了,除非指定了一個(gè)stdio配置(不和父進(jìn)程之間有聯(lián)系)。如果父進(jìn)程的stdio是繼承的,那么子進(jìn)程依然會(huì)和控制終端之間保持關(guān)系。

options.stdio

這個(gè)選項(xiàng)用于配置父進(jìn)程和子進(jìn)程之間的管道。默認(rèn)情況下,子進(jìn)程的stdin,stdout,stderr導(dǎo)向了ChildProcess這個(gè)對象的child.stdin,child.stdout,child.stderr流,這和設(shè)置stdio為['pipe','pipe','pipe']是一樣的。stdio可以是下面的任何一個(gè)字符串:

'pipe':相當(dāng)于['pipe','pipe','pipe'],為默認(rèn)選項(xiàng)

'ignore':相當(dāng)于['ignore','ignore','ignore']

'inherit':相當(dāng)于[process.stdin,process.stdout,process.stderr]或者[0,1,2]

一般情況下,stdio是一個(gè)數(shù)組,每一個(gè)選項(xiàng)對應(yīng)于子進(jìn)程的fd。其中0,1,2分別對應(yīng)于stdin,stdout,stderr。如果還設(shè)置了多于的fds那么就會(huì)用于創(chuàng)建父進(jìn)程和子進(jìn)程之間的額外的管道,可以是下面的任何一個(gè)值:

'pipe':為子進(jìn)程和父進(jìn)程之間創(chuàng)建一個(gè)管道。父進(jìn)程管道的末端會(huì)作為child_process對象的ChildProcess.stdio[fd]而存在。fds0-2創(chuàng)建的管道在ChildProcess.stdin,ChildProcess.stdout,ChildProcess.stderr也是存在的

'ipc':用于創(chuàng)建IPC通道用于在父進(jìn)程和子進(jìn)程之間傳輸消息或者文件描述符。ChildProcess對象最多有一個(gè)IPC stdio文件描述符,使用這個(gè)配置可以啟用ChildProcess的send方法,如果父進(jìn)程在文件描述符里面寫入了JSON對象,那么ChildProcess.on("message")事件就會(huì)在父進(jìn)程上觸發(fā)。如果子進(jìn)程是Node.js進(jìn)程,那么ipc配置就會(huì)啟用子進(jìn)程的process.send(), process.disconnect(), process.on('disconnect'), and process.on('message')方法。

'ignore':讓Node.js子進(jìn)程忽視文件描述符。因?yàn)镹ode.js總是會(huì)為子進(jìn)程開啟fds0-2,設(shè)置為ignore就會(huì)導(dǎo)致Node.js去開啟/dev/null,同時(shí)把這個(gè)值設(shè)置到子進(jìn)程的fd上面。

'strem':和子進(jìn)程之間共享一個(gè)可讀或者可寫流,比如file,socket,pipe。這個(gè)stream的文件描述符和子進(jìn)程的文件描述符fd是重復(fù)的。注意:流必須有自己的文件描述符

正整數(shù):表示父進(jìn)程的打開的文件描述符。和stream對象可以共享一樣,這個(gè)文件描述符在父子進(jìn)程之間也是共享的
null/undefined:使用默認(rèn)值。stdio的fds0,1,2管道被創(chuàng)建(stdin,stdout,stderr)。對于fd3或者fdn,默認(rèn)為'ignore'

const spawn = require('child_process').spawn; 
// Child will use parent's stdios 
//使用父進(jìn)程的stdios 
spawn('prg', [], { stdio: 'inherit' }); 
//產(chǎn)生一個(gè)共享process.stderr的子進(jìn)程 
// Spawn child sharing only stderr 
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] }); 
// Open an extra fd=4, to interact with programs presenting a 
// startd-style interface. 
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); 

注意:當(dāng)子進(jìn)程和父進(jìn)程之間建立了IPC通道,同時(shí)子進(jìn)程為Node.js進(jìn)程,這時(shí)候開啟的具有IPC通道的子進(jìn)程(使用unref)直到子進(jìn)程注冊了一個(gè)disconnect的事件處理句柄process.on('disconnect'),這樣就會(huì)允許子進(jìn)程正常退出而不會(huì)由于IPC通道的打開而持續(xù)運(yùn)行。

Class: ChildProcess

這個(gè)類的實(shí)例是一個(gè)EventEmitters,用于代表產(chǎn)生的子進(jìn)程。這個(gè)類的實(shí)例不能直接創(chuàng)建,必須使用 child_process.spawn(), child_process.exec(), child_process.execFile(), or child_process.fork()來完成

'close'事件:

其中code表示子進(jìn)程退出的時(shí)候的退出碼;signal表示終止子進(jìn)程發(fā)出的信號;這個(gè)事件當(dāng)子進(jìn)程的stdio stream被關(guān)閉的時(shí)候觸發(fā),和exit事件的區(qū)別是多個(gè)進(jìn)程可能共享同一個(gè)stdio streams!(所以一個(gè)進(jìn)程退出了也就是exit被觸發(fā)了,這時(shí)候close可能不會(huì)觸發(fā))

'exit'事件:

其中code表示子進(jìn)程退出的時(shí)候的退出碼;signal表示終止子進(jìn)程發(fā)出的信號。這個(gè)事件當(dāng)子進(jìn)程結(jié)束的時(shí)候觸發(fā),如果進(jìn)程退出了那么code表示進(jìn)程退出的exit code,否則沒有退出就是null。如果進(jìn)程是由于收到一個(gè)信號而終止的,那么signal就是這個(gè)信號,是一個(gè)string,默認(rèn)為null。

注意:如果exit事件被觸發(fā)了,子進(jìn)程的stdio stream可能還是打開的;Node.js為SUGUBT,SIGTERM創(chuàng)建信號處理器,而且Node.js進(jìn)程在收到信號的時(shí)候不會(huì)馬上停止。Node.js會(huì)進(jìn)行一系列的清理工作,然后才re-raise handled signal。見waitpid(2)

'disconnect'事件:

在子進(jìn)程或者父進(jìn)程中調(diào)用ChildProcess.disconnect()方法的時(shí)候會(huì)觸發(fā)。這時(shí)候就不能再發(fā)送和接受信息了,這是ChildProcess.connected就是false了

'error'事件:

當(dāng)進(jìn)程無法產(chǎn)生的時(shí)候,進(jìn)程無法終止的時(shí)候,為子進(jìn)程發(fā)送消息失敗的時(shí)候就會(huì)觸發(fā)。注意:當(dāng)產(chǎn)生錯(cuò)誤的時(shí)候exit事件可能會(huì)也可能不會(huì)觸發(fā)。如果你同時(shí)exit和error事件,那么就要注意是否會(huì)無意中多次調(diào)用事件處理函數(shù)

'message'事件:

message參數(shù)表示一個(gè)解析后的JSON對象或者初始值;sendHandle可以是一個(gè)net.Socket或者net.Server對象或者undefined。當(dāng)子進(jìn)程調(diào)用process.send時(shí)候觸發(fā)

child.connected:

調(diào)用了disconnect方法后就會(huì)是false。表示是否可以在父進(jìn)程和子進(jìn)程之間發(fā)送和接受數(shù)據(jù),當(dāng)值為false就不能發(fā)送數(shù)據(jù)了
 child.disconnect()

關(guān)閉子進(jìn)程和父進(jìn)程之間的IPC通道,這時(shí)候子進(jìn)程可以正常退出如果沒有其他的連接使得他保持活動(dòng)。這時(shí)候父進(jìn)程的child.connected和子進(jìn)程的process.connected就會(huì)設(shè)置為false,這時(shí)候不能傳輸數(shù)據(jù)了。disconnect事件當(dāng)進(jìn)程沒有消息接收到的時(shí)候被觸發(fā),當(dāng)調(diào)用child.disconnect時(shí)候會(huì)立即觸發(fā)。注意:當(dāng)子進(jìn)程為Node.js實(shí)例的時(shí)候如child_process.fork,這時(shí)候process.disconnect方法就會(huì)在子進(jìn)程中調(diào)用然后關(guān)閉IPC通道。

child.kill([signal])

為子進(jìn)程傳入消息,如果沒有指定參數(shù)那么就會(huì)發(fā)送SIGTERM信號,可以參見signal(7)來查看一系列信號

const spawn = require('child_process').spawn; 
const grep = spawn('grep', ['ssh']); 
grep.on('close', (code, signal) => { 
 console.log( 
  `child process terminated due to receipt of signal ${signal}`); 
}); 
// Send SIGHUP to process 
grep.kill('SIGHUP'); 

ChildProcess對象在無法傳輸信號的時(shí)候會(huì)觸發(fā)error事件。為一個(gè)已經(jīng)退出的子進(jìn)程發(fā)送信號雖然無法報(bào)錯(cuò)但是可能導(dǎo)致無法預(yù)料的結(jié)果。特別的,如果這個(gè)PID已經(jīng)被分配給另外一個(gè)進(jìn)程那么這時(shí)候也會(huì)導(dǎo)致無法預(yù)料的結(jié)果。

child.pid:

返回進(jìn)程的PID值

const spawn = require('child_process').spawn; 
const grep = spawn('grep', ['ssh']); 
console.log(`Spawned child pid: ${grep.pid}`); 
grep.stdin.end();//通過grep.stdin.end結(jié)束 

child.send(message[, sendHandle][, callback])

當(dāng)父子進(jìn)程之間有了IPC通道,child.send就會(huì)為子進(jìn)程發(fā)送消息,當(dāng)子進(jìn)程為Node.js實(shí)例,那么可以用process.on('message')事件接收

父進(jìn)程為:

const cp = require('child_process'); 
const n = cp.fork(`${__dirname}/sub.js`); 
n.on('message', (m) => { 
 console.log('PARENT got message:', m); 
}); 
n.send({ hello: 'world' }); 

子進(jìn)程為:

process.on('message', (m) => { 
 console.log('CHILD got message:', m); 
}); 
process.send({ foo: 'bar' }); 

子進(jìn)程使用process.send方法為父進(jìn)程發(fā)送消息。有一個(gè)特例,發(fā)送{cmd: 'NODE_foo'}。當(dāng)一個(gè)消息在他的cmd屬性中包含一個(gè)NODE_前綴會(huì)被看做使用Node.js核心(被Node.js保留)。這時(shí)候不會(huì)觸發(fā)子進(jìn)程的process.on('message')。而是使用process.on('internalMessage')事件,同時(shí)會(huì)被Node.js內(nèi)部消費(fèi),一般不要使用這個(gè)方法。sendHandle這個(gè)用于給子進(jìn)程傳入一個(gè)TCP Server或者一個(gè)socket,為process.on('message')回調(diào)的第二個(gè)參數(shù)接受。callback當(dāng)消息已經(jīng)發(fā)送,但是子進(jìn)程還沒有接收到的時(shí)候觸發(fā),這個(gè)函數(shù)只有一個(gè)參數(shù)成功為null否則為Error對象。如果沒有指定callback同時(shí)消息也不能發(fā)送ChildProcess就會(huì)觸發(fā)error事件。當(dāng)子進(jìn)程已經(jīng)退出就會(huì)出現(xiàn)這個(gè)情況。child.send返回false如果父子進(jìn)程通道已經(jīng)關(guān)閉,或者積壓的沒有傳輸?shù)臄?shù)據(jù)超過一定的限度,否則這個(gè)方法返回true。這個(gè)callback方法可以用于實(shí)現(xiàn)流控制:

下面是發(fā)送一個(gè)Server的例子:

const child = require('child_process').fork('child.js'); 
// Open up the server object and send the handle. 
const server = require('net').createServer(); 
server.on('connection', (socket) => { 
 socket.end('handled by parent'); 
}); 
server.listen(1337, () => { 
 child.send('server', server); 
}); 

子進(jìn)程接受這個(gè)消息:

process.on('message', (m, server) => { 
 if (m === 'server') { 
  server.on('connection', (socket) => { 
   socket.end('handled by child'); 
  }); 
 } 
}); 

這時(shí)候server就被子進(jìn)程和父進(jìn)程共享了,一些連接可以被父進(jìn)程處理,一些被子進(jìn)程處理。上面的例子如果使用dgram那么就應(yīng)該message事件而不是connection,使用server.bind而不是server.listen,但是當(dāng)前只在UNIX平臺(tái)上可行。
下面的例子展示發(fā)送一個(gè)socket對象(產(chǎn)生兩個(gè)子進(jìn)程,處理normal和special優(yōu)先級):

父進(jìn)程為:

const normal = require('child_process').fork('child.js', ['normal']); 
const special = require('child_process').fork('child.js', ['special']); 
// Open up the server and send sockets to child 
const server = require('net').createServer(); 
server.on('connection', (socket) => { 
 // If this is special priority 
 if (socket.remoteAddress === '74.125.127.100') { 
  special.send('socket', socket); 
  return; 
 } 
 // This is normal priority 
 normal.send('socket', socket); 
}); 
server.listen(1337); 

子進(jìn)程為:

process.on('message', (m, socket) => { 
 if (m === 'socket') { 
  socket.end(`Request handled with ${process.argv[2]} priority`); 
 } 
}); 

當(dāng)socket被發(fā)送到子進(jìn)程的時(shí)候那么父進(jìn)程已經(jīng)無法追蹤這個(gè)socket什么時(shí)候被銷毀的。這時(shí)候.connections屬性就會(huì)成為null,因此我們建議不要使用.maxConnections。注意:這個(gè)方法在內(nèi)部JSON.stringify去序列化消息

child.stderr:

一個(gè)流對象,是一個(gè)可讀流表示子進(jìn)程的stderr。他是child.stdio[2]的別名,兩者表示同樣的值。如果子進(jìn)程是通過stdio[2]產(chǎn)生的,設(shè)置的不是pipe那么值就是undefined。

child.stdin:

一個(gè)可寫的流對象。注意:如果子進(jìn)程等待讀取輸入,那么子進(jìn)程會(huì)一直等到流調(diào)用了end方法來關(guān)閉的時(shí)候才會(huì)繼續(xù)讀取。如果子進(jìn)程通過stdio[0]產(chǎn)生,同時(shí)不是設(shè)置的pipe那么值就是undefined。child.stdin是child.stdio[0]的別名,表示同樣的值。

const spawn = require('child_process').spawn;  
const grep = spawn('grep', ['ssh']);  
console.log(`Spawned child pid: ${grep.pid}`);  
grep.stdin.end();//通過grep.stdin.end結(jié)束  

child.stdio:

一個(gè)子進(jìn)程管道的稀疏數(shù)組,是 child_process.spawn()函數(shù)的stdio選項(xiàng),同時(shí)這個(gè)值被設(shè)置為pipe。child.stdio[0], child.stdio[1], 和 child.stdio[2]也可以通過child.stdin, child.stdout, 和 child.stderr訪問。下面的例子中只有子進(jìn)程的fd1(也就是stdout)被設(shè)置為管道,因此只有父進(jìn)程的child.stdio[1]是一個(gè)流,其他的數(shù)組中對象都是null:

const assert = require('assert'); 
const fs = require('fs'); 
const child_process = require('child_process'); 
const child = child_process.spawn('ls', { 
  stdio: [ 
   0, // Use parents stdin for child 
   'pipe', // Pipe child's stdout to parent 
   fs.openSync('err.out', 'w') // Direct child's stderr to a file 
  ] 
}); 
assert.equal(child.stdio[0], null); 
assert.equal(child.stdio[0], child.stdin); 
assert(child.stdout); 
assert.equal(child.stdio[1], child.stdout); 
assert.equal(child.stdio[2], null); 
assert.equal(child.stdio[2], child.stderr); 

child.stdout:

一個(gè)可讀流,代表子進(jìn)程的stdout。如果子進(jìn)程產(chǎn)生的時(shí)候吧stdio[1]設(shè)置為除了pipe以外的任何數(shù),那么值就是undefined。其值和child.stdio[1]一樣

 以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • npm run dev和npm run serve的區(qū)別小結(jié)

    npm run dev和npm run serve的區(qū)別小結(jié)

    npm run serve和npm run dev是在開發(fā)階段使用npm運(yùn)行腳本的兩種常見命令,本文就來介紹一下這兩者的區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Node.js如何自動(dòng)審核團(tuán)隊(duì)的代碼

    Node.js如何自動(dòng)審核團(tuán)隊(duì)的代碼

    在項(xiàng)目開發(fā)中,統(tǒng)一團(tuán)隊(duì)的代碼風(fēng)格很重要,本文介紹如何用Node.js來自動(dòng)審核,來提高您的開發(fā)速度。
    2016-07-07
  • Node.js使用express寫接口的具體代碼

    Node.js使用express寫接口的具體代碼

    這篇文章主要介紹了Node.js使用express寫接口,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Node.js中的模塊路徑解析規(guī)則和子模塊包

    Node.js中的模塊路徑解析規(guī)則和子模塊包

    NodeJS特性如事件驅(qū)動(dòng)、異步編程、無阻塞IO,這些特性為它帶來了高效的性能和更少的代碼,require函數(shù)支持斜杠(/)或盤符(C:)開頭的絕對路徑,也支持./開頭的相對路徑,為了便于管理和使用,我們可以把由多個(gè)子模塊組成的大模塊稱做包,并把所有子模塊放在同一個(gè)目錄里
    2023-11-11
  • node項(xiàng)目使用http模塊發(fā)送get-post請求方式

    node項(xiàng)目使用http模塊發(fā)送get-post請求方式

    這篇文章主要介紹了node項(xiàng)目使用http模塊發(fā)送get-post請求方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • Electron架構(gòu)深入探究

    Electron架構(gòu)深入探究

    這篇文章主要為大家介紹了Electron架構(gòu)深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 如何使用npm安裝yarn詳解

    如何使用npm安裝yarn詳解

    Yarn是一個(gè)新的快速安全可信賴的可以替代NPM的依賴管理工具,下面這篇文章主要給大家介紹了關(guān)于如何使用npm安裝yarn的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • Node.js基礎(chǔ)入門之回調(diào)函數(shù)及異步與同步詳解

    Node.js基礎(chǔ)入門之回調(diào)函數(shù)及異步與同步詳解

    Node.js是一個(gè)基于Chrome?V8引擎的JavaScript運(yùn)行時(shí)。類似于Java中的JRE,.Net中的CLR。本文將詳細(xì)為大家介紹Node.js中的回調(diào)函數(shù)及異步與同步,感興趣的可以了解一下
    2022-03-03
  • 修改npm全局安裝模式的路徑方法

    修改npm全局安裝模式的路徑方法

    今天小編就為大家分享一篇修改npm全局安裝模式的路徑方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié)

    nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié)

    這篇文章主要介紹了nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié),對FS模塊的大部份異步函數(shù)做了介紹,而且用中文注釋,這下用起來方便了,需要的朋友可以參考下
    2014-06-06

最新評論