node js fork php,Node.js中execFile,spawn,exec和fork简介
Node.js中execFile,spawn,exec和fork簡介
Node.js子流程child_process模塊提供四種不同方法執行外部應用:
所有這些都是異步,調用這些方法會返回一個對象,這對象是ChildProcess類的實例。
1. execFile
用于執行一個外部應用,應用退出后會返回一些可選蠶食和帶有緩沖輸出的callback。
child_process.execFile(file[, args][, options][, callback])
文件?將要執行外部應用的可執行文件的路徑或名稱
參數?是字符串數組
可選?
cwd??子流程當前工作目錄
env??key-value環境值對
encoding??(默認: ‘utf8’)
timeout??(Default: 0)
maxBuffer??標準輸入或輸出的大量數據 (in bytes) – 如果超過子流程會被殺死 (Default:200\*1024)
killSignal??(Default: ‘SIGTERM’)
uid??流程的用戶標識符 (See?setuid(2).)
gid??流程的群組標識符(See?setgid(2).)
當外部應用存在時,Node程序將攜帶參數"-version"被執行,當外部應用退出時,回調函數被調用,回調函數帶有子流程的標準輸入輸出,來自外部應用的標準輸出將被內部緩沖保存。
運行下面代碼將打印當前node版本:
const execFile = require( 'child_process').execFile;
const child = execFile( 'node', [ '--version'], ( error, stdout, stderr) => {
if ( error) {
console.error( 'stderr', stderr);
throw error;
}
console.log( 'stdout', stdout);
});
node是如何發現外部應用?它是由PATH環境變量,其中會指定一系列目錄,可執行的外部應用駐留在這些目錄中,如果外部應該被發現存在,無需該外部應用的絕對路徑或相對路徑就會被定位。
execFile是當需要執行外部應用并獲得輸出時使用,我們能使用它運行一個圖片處理應用將圖片從PNG轉為JPG格式,我們只關心其成功與否,當外部應用產生大量數據以及我們需要實時使用這些數據時,execFile就不要使用。
2.spawn
spawn?方法會在新的流程執行外部應用,返回I/O的一個流接口。
child_process.spawn(command[, args][, options])
使用案例:
const spawn = require( 'child_process').spawn;
const fs = require( 'fs');
function resize( req, resp) {
const args = [
"-", // use stdin
"-resize", "640x", // resize width to 640
"-resize", "x360
"-gravity", "center", // sets the offset to the center
"-crop", "640x360+0+0", // crop
"-" // output to stdout
];
const streamIn = fs.createReadStream( './path/to/an/image');
const proc = spawn( 'convert', args);
streamIn.pipe( proc.stdin);
proc.stdout.pipe( resp);
}
上面是一個express.js控制器函數中代碼,我們使用流從一個圖片文件讀取,然后使用spawn方法生成convert程序,我們使用圖片流喂給ChildProcess proc,只要這個proc對象產生數據,我們寫入數據到一個可寫的流中,用戶無需等待整個圖片轉換完畢就能立即看見圖片。
spawn返回一個對象流,對于輸出大量數據然后需要讀取的應用適合,因為是基于流,所有流好處有:
低內存損耗
自動處理后壓back-pressure
在緩沖塊中懶生產或消費數據
基于事件且非堵塞
緩沖可以讓你超過V8 heap內存限制
3.exec
這個方法將會生成一個子shell,能夠在shell中執行命令,并緩沖產生的數據,當子流程完成后回調函數將會被調用,可帶有:
當命令成功執行,緩沖的數據
當命令失敗,錯誤信息
child_process.exec(command[, options][, callback])
與execFile 和 spawn相比,exec并沒有參數,因為exec允許我們在shell中執行多個命令,當使用exec時,我們如果需要傳輸參數到命令行,它們應該作為整個命令字符串的一部分。
下面代碼將會輸出當前目錄下所有遞歸條目:
const exec = require( 'child_process').exec;
exec( 'for i in $( ls -LR ); do echo item: $i; done', ( e, stdout, stderr)=> {
if ( e instanceof Error) {
console.error( e);
throw e;
}
console.log( 'stdout ', stdout);
console.log( 'stderr ', stderr);
});
當在一個shell中運行命令,我們能實現在shell中所有功能,比如管道 重定向:
const exec = require( 'child_process').exec;
exec( 'netstat -aon | find "9000"', ( e, stdout, stderr)=> {
if ( e instanceof Error) {
console.error( e);
throw e;
}
console.log( 'stdout ', stdout);
console.log( 'stderr ', stderr);
});
上面案例中,node會生成一個子shell,并執行命令: netstat -aon | find “9000”
exec只有需要利用shell功能時才能使用。
4.fork
child_process.fork()方法是child_process.spawn()特殊情況,子流程返回一個ChildProcess對象,這個ChildProcess會有附加通訊通道,允許消息在父子之間來回穿梭。fork方法會打開一個IPC通道,允許Node流程之間傳遞消息:
如在子流程,?process.on(‘message’)?和?process.send(‘message to parent’)?能被用來接受和發送數據
入在父流程,?使用child.on(‘message’)?和?child.send(‘message to child’)
每個流程都有自己的內存,都有它們自己的V8實例,啟動至少30毫秒,每個大小是10mb
//parent.js
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' });
//sub.js
process.on( 'message', ( m) => {
console.log( 'CHILD got message:', m);
});
process.send({ foo: 'bar' });
因為Node主流程是單線程的,長期運行任務如計算等會堵塞主流程,因此,進來的請求不能被處理,應用變得不可響應,將這些長期運行任務放入主流程之外運行,fork一個新的node流程專門處理,這樣主流程能夠進行處理進來的請求保持可響應性。
總結
以上是生活随笔為你收集整理的node js fork php,Node.js中execFile,spawn,exec和fork简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对数周期天线hfss建模_HFSS也有金
- 下一篇: xib 设置阴影_影响uiview阴影的