在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ 應(yīng)用場景
文本編碼
小結(jié)
API 走馬觀花
API 走馬觀花
迭代
小結(jié)
運(yùn)行
回調(diào)
需求
代碼設(shè)計模式
進(jìn)程介紹
模塊
工程目錄
小結(jié)
小結(jié)
遍歷目錄
小結(jié)
小結(jié)
API 走馬觀花
用途
NPM
小結(jié)
安裝
網(wǎng)絡(luò)操作介紹
二進(jìn)制模塊
什么是 NodeJS
命令行程序
靈機(jī)一點(diǎn)
域(Domain)
應(yīng)用場景
模塊路徑解析規(guī)則
文件拷貝

應(yīng)用場景

和進(jìn)程管理相關(guān)的 API 單獨(dú)介紹起來比較枯燥,因此這里從一些典型的應(yīng)用場景出發(fā),分別介紹一些重要 API 的使用方法。

如何獲取命令行參數(shù)

在 NodeJS 中可以通過 process.argv 獲取命令行參數(shù)。但是比較意外的是,node 執(zhí)行程序路徑和主模塊文件路徑固定占據(jù)了 argv[0]和 argv[1]兩個位置,而第一個命令行參數(shù)從 argv[2]開始。為了讓 argv 使用起來更加自然,可以按照以下方式處理。

function main(argv) {
    // ...
}

main(process.argv.slice(2));

如何退出程序

通常一個程序做完所有事情后就正常退出了,這時程序的退出狀態(tài)碼為 0。或者一個程序運(yùn)行時發(fā)生了異常后就掛了,這時程序的退出狀態(tài)碼不等于 0。如果我們在代碼中捕獲了某個異常,但是覺得程序不應(yīng)該繼續(xù)運(yùn)行下去,需要立即退出,并且需要把退出狀態(tài)碼設(shè)置為指定數(shù)字,比如1,就可以按照以下方式:

try {
    // ...
} catch (err) {
    // ...
    process.exit(1);
}

如何控制輸入輸出

NodeJS 程序的標(biāo)準(zhǔn)輸入流(stdin)、一個標(biāo)準(zhǔn)輸出流(stdout)、一個標(biāo)準(zhǔn)錯誤流(stderr)分別對應(yīng) process.stdin、process.stdout 和 process.stderr,第一個是只讀數(shù)據(jù)流,后邊兩個是只寫數(shù)據(jù)流,對它們的操作按照對數(shù)據(jù)流的操作方式即可。例如,console.log 可以按照以下方式實(shí)現(xiàn)。

function log() {
    process.stdout.write(
        util.format.apply(util, arguments) + '\n');
}

如何降權(quán)

在 Linux 系統(tǒng)下,我們知道需要使用 root 權(quán)限才能監(jiān)聽 1024 以下端口。但是一旦完成端口監(jiān)聽后,繼續(xù)讓程序運(yùn)行在 root 權(quán)限下存在安全隱患,因此最好能把權(quán)限降下來。以下是這樣一個例子。

http.createServer(callback).listen(80, function () {
    var env = process.env,
        uid = parseInt(env['SUDO_UID'] || process.getuid(), 10),
        gid = parseInt(env['SUDO_GID'] || process.getgid(), 10);

    process.setgid(gid);
    process.setuid(uid);
});

上例中有幾點(diǎn)需要注意:

如果是通過 sudo 獲取 root 權(quán)限的,運(yùn)行程序的用戶的 UID 和 GID 保存在環(huán)境變量 SUDO_UID 和 SUDO_GID 里邊。如果是通過 chmod +s 方式獲取 root 權(quán)限的,運(yùn)行程序的用戶的 UID 和 GID 可直接通過 process.getuid 和 process.getgid 方法獲取。

process.setuid 和 process.setgid 方法只接受 number 類型的參數(shù)。

降權(quán)時必須先降 GID 再降 UID,否則順序反過來的話就沒權(quán)限更改程序的 GID了。

如何創(chuàng)建子進(jìn)程

以下是一個創(chuàng)建 NodeJS 子進(jìn)程的例子。

var child = child_process.spawn('node', [ 'xxx.js' ]);

child.stdout.on('data', function (data) {
    console.log('stdout: ' + data);
});

child.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
});

child.on('close', function (code) {
    console.log('child process exited with code ' + code);
});

上例中使用了.spawn(exec, args, options)方法,該方法支持三個參數(shù)。第一個參數(shù)是執(zhí)行文件路徑,可以是執(zhí)行文件的相對或絕對路徑,也可以是根據(jù) PATH 環(huán)境變量能找到的執(zhí)行文件名。第二個參數(shù)中,數(shù)組中的每個成員都按順序?qū)?yīng)一個命令行參數(shù)。第三個參數(shù)可選,用于配置子進(jìn)程的執(zhí)行環(huán)境與行為。

另外,上例中雖然通過子進(jìn)程對象的.stdout.stderr訪問子進(jìn)程的輸出,但通過 options.stdio 字段的不同配置,可以將子進(jìn)程的輸入輸出重定向到任何數(shù)據(jù)流上,或者讓子進(jìn)程共享父進(jìn)程的標(biāo)準(zhǔn)輸入輸出流,或者直接忽略子進(jìn)程的輸入輸出。

進(jìn)程間如何通訊

在 Linux 系統(tǒng)下,進(jìn)程之間可以通過信號互相通信。以下是一個例子。

/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ]);

child.kill('SIGTERM');

/* child.js */
process.on('SIGTERM', function () {
    cleanUp();
    process.exit(0);
});

在上例中,父進(jìn)程通過.kill方法向子進(jìn)程發(fā)送 SIGTERM 信號,子進(jìn)程監(jiān)聽 process 對象的 SIGTERM 事件響應(yīng)信號。不要被.kill方法的名稱迷惑了,該方法本質(zhì)上是用來給進(jìn)程發(fā)送信號的,進(jìn)程收到信號后具體要做啥,完全取決于信號的種類和進(jìn)程自身的代碼。

另外,如果父子進(jìn)程都是 NodeJS 進(jìn)程,就可以通過 IPC(進(jìn)程間通訊)雙向傳遞數(shù)據(jù)。以下是一個例子。

/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ], {
        stdio: [ 0, 1, 2, 'ipc' ]
    });

child.on('message', function (msg) {
    console.log(msg);
});

child.send({ hello: 'hello' });

/* child.js */
process.on('message', function (msg) {
    msg.hello = msg.hello.toUpperCase();
    process.send(msg);
});

可以看到,父進(jìn)程在創(chuàng)建子進(jìn)程時,在 options.stdio 字段中通過 ipc 開啟了一條 IPC 通道,之后就可以監(jiān)聽子進(jìn)程對象的 message 事件接收來自子進(jìn)程的消息,并通過.send方法給子進(jìn)程發(fā)送消息。在子進(jìn)程這邊,可以在 process 對象上監(jiān)聽 message 事件接收來自父進(jìn)程的消息,并通過.send方法向父進(jìn)程發(fā)送消息。數(shù)據(jù)在傳遞過程中,會先在發(fā)送端使用 JSON.stringify 方法序列化,再在接收端使用 JSON.parse 方法反序列化。

如何守護(hù)子進(jìn)程

守護(hù)進(jìn)程一般用于監(jiān)控工作進(jìn)程的運(yùn)行狀態(tài),在工作進(jìn)程不正常退出時重啟工作進(jìn)程,保障工作進(jìn)程不間斷運(yùn)行。以下是一種實(shí)現(xiàn)方式。

/* daemon.js */
function spawn(mainModule) {
    var worker = child_process.spawn('node', [ mainModule ]);

    worker.on('exit', function (code) {
        if (code !== 0) {
            spawn(mainModule);
        }
    });
}

spawn('worker.js');

可以看到,工作進(jìn)程非正常退出時,守護(hù)進(jìn)程立即重啟工作進(jìn)程。