Node.js多程式

小小浪花一朵發表於2019-02-16

Node.js多程式
Node.js單執行緒模式執行的,使用事件處理併發。

exec()

使用子程式的執行命令,快取子程式的輸出。並將子程式的輸出以回撥函式引數的形式進行返回

process.argv()

當引數為0時

是node的檔案絕對地址

當引數為1時

是該檔案的絕對地址

當引數為2時

是命令第一個引數。

child_process.exec

回撥函式有三個選項,error, stdout, stderr
error 為程式執行的錯誤,正常執行會返回一個null
stdout 為程式的正常輸出
stderr 為程式錯誤輸出

/*master.js*/
const fs = require(`fs`);
const child_process = require(`child_process`);
 
for(var i=0; i<3; i++) {
    var count = 0;
    var workerProcess = child_process.exec(`node support.js ` +i, function (err, std, stderr) {
        if (err) {
            console.log(err.stack);
            console.log(`Error code: `+err.code);
            console.log(`Signal received: `+err.signal);
        }
        console.log(`---------------------`);
        console.log(i);
        console.log(`stdout: ` + std);
        console.log(`stderr: ` + stderr);
    });
 
    workerProcess.on(`exit`, function (code) {
        console.log(`子程式已退出,退出碼 `+code);
        console.log(`執行順序` + count++);
    });
}
/*support.js*/
/*support.js*/
console.log("程式 " + process.argv[2] + " 執行。" );

執行結果

PS C:UsersmingmDesktop	est> node master.js
子程式已退出,退出碼 0
執行順序0
---------------------
3
stdout: 程式 0 執行。

stderr:
子程式已退出,退出碼 0
執行順序1
---------------------
3
stdout: 程式 1 執行。

stderr:
子程式已退出,退出碼 0
執行順序2
---------------------
3
stdout: 程式 2 執行。

stderr:
PS C:UsersmingmDesktop	est>

node.js的執行為非同步執行,導致先迴圈3次,每次提交。
所以輸出i的值全為3
由於先執行子程式,子程式執行完畢以後,觸發exit事件,
執行

        console.log(`子程式已退出,退出碼 `+code);
        console.log(`執行順序` + count++);

該兩句。
接著執行

        console.log(`---------------------`);
        console.log(i);
        console.log(`stdout: ` + std);
        console.log(`stderr: ` + stderr);

執行完畢。
node最大的特點是非同步執行。

spawn()方法

同樣也是使用指定的命令列,建立新程式。

PS C:UsersmingmDesktop	est> node master.js
stdout程式 0 執行。

stdout程式 1 執行。

子程式退出0
stdout程式 2 執行。

子程式退出0
子程式退出0
PS C:UsersmingmDesktop	est> node master.js
stdout程式 0 執行。

子程式退出0
stdout程式 1 執行。

stdout程式 2 執行。

子程式退出0
子程式退出0
PS C:UsersmingmDesktop	est> node master.js
stdout程式 0 執行。

stdout程式 1 執行。

子程式退出0
stdout程式 2 執行。

子程式退出0
子程式退出0
PS C:UsersmingmDesktop	est>

node執行非同步相當魔幻
飄忽不定

/*master.js*/
const fs = require(`fs`);
const child_process = require(`child_process`);

for(var i=0; i<3; i++) {
    var workerProcess = child_process.spawn(`node`, [`support.js`, i]);

    // 繫結兩個事件
    workerProcess.stdout.on(`data`, (data) => {
        console.log(`stdout` + data);
    });

    workerProcess.stderr.on(`data`, (data) => {
        console.log(`stderr`, + data);
    });

    // 設定退出事件
    workerProcess.on(`close`, (code) => {
        console.log(`子程式退出` + code);
    });
};
/*support.js*/
console.log("程式 " + process.argv[2] + " 執行。" );

和exec()的區別在於exec()是直接回撥函式,而spawn()是直接繫結事件

fork()方法

PS C:UsersmingmDesktop	est> node master.js
程式 0 執行。
程式 1 執行。
程式 2 執行。
子程式已經退出0
子程式已經退出0
子程式已經退出0
PS C:UsersmingmDesktop	est>
const fs = require(`fs`);
const child_process = require(`child_process`);

for(var i=0; i<3; i++) {
    var worker_process = child_process.fork(`support.js`, [i]);

    worker_process.on(`close`, (code) => {
        console.log(`子程式已經退出` + code);
    });
}

還是喜歡fork方法。fork很方便。沒有那麼多的非同步讓人頭疼。

相關文章