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

Node.js中創(chuàng)建和管理外部進(jìn)程詳解

 更新時(shí)間:2014年08月16日 11:13:30   作者:Jack Yao  
這篇文章主要介紹了Node.js中創(chuàng)建和管理外部進(jìn)程詳解,本文講解了執(zhí)行外部命令的方法、子進(jìn)程相關(guān)內(nèi)容等,需要的朋友可以參考下

Node被設(shè)計(jì)用來(lái)高效的處理I/O操作,但是你應(yīng)該知道,有些類(lèi)型的程序并不適合這種模式。比如,如果你打算用Node處理一個(gè)CPU密集的任務(wù),你可能會(huì)堵塞事件循環(huán),并因此降低了程序的響應(yīng)。替代辦法是,把CPU密集的任務(wù)分配給一個(gè)單獨(dú)的進(jìn)程來(lái)處理,從而釋放事件循環(huán)。Node允許你產(chǎn)生進(jìn)程,并把這個(gè)新進(jìn)程做為它父進(jìn)程的子進(jìn)程。在Node里,子進(jìn)程可以和父進(jìn)程進(jìn)行雙向通信,而且在某種程度上,父進(jìn)程還可以監(jiān)控和管理子進(jìn)程。

另外一種需要使用子進(jìn)程的情況是,當(dāng)你想簡(jiǎn)單地執(zhí)行一個(gè)外部命令,并讓Node獲取命令的返回值時(shí)。比如,你可以執(zhí)行一個(gè)UNIX命令、腳本或者其他那些不能在Node里直接執(zhí)行的命令。

本章將向你展示如何執(zhí)行外部命令,創(chuàng)建,并和子進(jìn)程通信,以及終結(jié)子進(jìn)程。重點(diǎn)是讓你了解如何在Node進(jìn)程外完成一系列任務(wù)。

執(zhí)行外部命令

當(dāng)你需要執(zhí)行一個(gè)外部shell命令或可執(zhí)行文件時(shí),你可以使用child_process模塊,像這樣導(dǎo)入它:

復(fù)制代碼 代碼如下:

var child_process = require(‘child_process')

然后可以用模塊內(nèi)的exec函數(shù)來(lái)執(zhí)行外部命令:
復(fù)制代碼 代碼如下:

var exec = child_process.exec;

exec(command,callback);


exec的第一個(gè)參數(shù)是你準(zhǔn)備執(zhí)行的shell命令字符串,第二個(gè)參數(shù)是一個(gè)回調(diào)函數(shù)。這個(gè)回調(diào)函數(shù)將會(huì)在exec執(zhí)行完外部命令或者有錯(cuò)誤發(fā)生時(shí)被調(diào)用?;卣{(diào)函數(shù)有三個(gè)參數(shù):error,stdout,stderr,看下面的例子:
復(fù)制代碼 代碼如下:

exec(‘ls',function(err,stdout,stderr){

         //譯者注:如果使用windows,可改為windows命令,比如dir,后面不再贅述

});

如果有錯(cuò)誤發(fā)生,第一個(gè)參數(shù)將會(huì)是一個(gè)Error類(lèi)的實(shí)例,如果第一個(gè)參數(shù)不包含錯(cuò)誤,那么第二個(gè)參數(shù)stdout將會(huì)包含命令的標(biāo)準(zhǔn)輸出。最后一個(gè)參數(shù)包含命令相關(guān)的錯(cuò)誤輸出。

列表8-1 展示了一個(gè)復(fù)雜些的執(zhí)行外部命令的例子

LISTING 8-1:執(zhí)行外部命令(源碼:chapter8/01_external_command.js)

復(fù)制代碼 代碼如下:

//導(dǎo)入child_process模塊的exec函數(shù)
var exec = require(‘child_process').exec;
//調(diào)用“cat *.js | wc -l”命令
exec(‘cat *.js | wc –l ‘, function(err, stdout, stderr ){  //第四行
         //命令退出或者調(diào)用失敗
         if( err ){
              //啟動(dòng)外部進(jìn)程失敗
              console.log(‘child_process 退出,錯(cuò)誤碼是:',err.code);
              return;
         }
}

第四行,我們把“cat *.js | wc -l”作為第一個(gè)參數(shù)傳遞給exec,你也可以嘗試任何其它命令,只要你在shell里使用過(guò)的命令都可以。

然后將一個(gè)回調(diào)函數(shù)作為第二個(gè)參數(shù),它將會(huì)在錯(cuò)誤發(fā)生或者子進(jìn)程終結(jié)的時(shí)候被調(diào)用。

還可以在回調(diào)函數(shù)之前傳遞第三個(gè)可選參數(shù),它包含一些配置選項(xiàng),比如:

復(fù)制代碼 代碼如下:

var exec = require(‘child_process').exec;       

var options ={
         timeout: 1000,
         killSignal: ‘SIGKILL'
     };

exec(‘cat *.js | wc –l ‘, options, function(err,stdout,stderr){
         //…
});

可以使用的參數(shù)有:

1.cwd —— 當(dāng)前目錄,可以指定當(dāng)前工作目錄。
2.encoding —— 子進(jìn)程輸出內(nèi)容的編碼格式,默認(rèn)值是”utf8”,也就是UTF-8編碼。如果子進(jìn)程的輸出不是utf8,你可以用這個(gè)參數(shù)來(lái)設(shè)置,支持的編碼格式有:

復(fù)制代碼 代碼如下:

ascii
utf8
ucs2
base64

如果你想了解Node支持的這些編碼格式的更多信息,請(qǐng)參考第4章“使用Buffer處理,編碼,解碼二進(jìn)制數(shù)據(jù)”。

1.timeout —— 以毫秒為單位的命令執(zhí)行超時(shí)時(shí)間,默認(rèn)是0,即無(wú)限制,一直等到子進(jìn)程結(jié)束。
2.maxBuffer —— 指定stdout流和stderr流允許輸出的最大字節(jié)數(shù),如果達(dá)到最大值,子進(jìn)程會(huì)被殺死。默認(rèn)值是200*1024。
3.killSignal —— 當(dāng)超時(shí)或者輸出緩存達(dá)到最大值時(shí)發(fā)送給子進(jìn)程的終結(jié)信號(hào)。默認(rèn)值是“SIGTERM”,它將給子進(jìn)程發(fā)送一個(gè)終結(jié)信號(hào)。通常都會(huì)使用這種有序的方式來(lái)結(jié)束進(jìn)程。當(dāng)用SIGTERM信號(hào)時(shí),進(jìn)程接收到以后還可以進(jìn)行處理或者重寫(xiě)信號(hào)處理器的默認(rèn)行為。如果目標(biāo)進(jìn)程需要,你可以同時(shí)向他傳遞其它的信號(hào)(比如SIGUSR1)。你也可以選擇發(fā)送一個(gè)SIGKILL信號(hào),它會(huì)被操作系統(tǒng)處理并強(qiáng)制立刻結(jié)束子進(jìn)程,這樣的話(huà),子進(jìn)程的任何清理操作都不會(huì)被執(zhí)行。

如果你想更進(jìn)一步的控制進(jìn)程的結(jié)束,可以使用child_process.spawn命令,后面會(huì)介紹。

1.evn —— 指定傳遞給子進(jìn)程的環(huán)境變量,默認(rèn)是null,也就是說(shuō)子進(jìn)程會(huì)繼承在它被創(chuàng)建之前的所有父進(jìn)程的環(huán)境變量。

注意:使用killSignal選項(xiàng),你可以以字符串的形式向目標(biāo)進(jìn)程發(fā)送信號(hào)。在Node里信號(hào)以字符串的形式存在,下面是UNIX信號(hào)和對(duì)應(yīng)默認(rèn)操作的列表:

你可能想為子進(jìn)程提供一組可擴(kuò)展的父級(jí)環(huán)境變量。如果直接去修改process.env對(duì)象,你會(huì)改變Node進(jìn)程內(nèi)所有模塊的環(huán)境變量,這樣會(huì)惹很多麻煩。替代方案是,創(chuàng)建一個(gè)新對(duì)象,復(fù)制process.env里的所有參數(shù),見(jiàn)例子8-2:

LISTING 8-2:使用參數(shù)化的環(huán)境變量來(lái)執(zhí)行命令(源碼:chapter8/02_env_vars_augment.js)

復(fù)制代碼 代碼如下:

var env = process.env,
    varName,
    envCopy = {},
    exec = require(‘child_prcess').exec;
//將process.env復(fù)制到envCopy
for( vaName in ev){
    envCopy[varName] = env[varName];
}

//設(shè)置一些自定義變量
envCopy[‘CUSTOM ENV VAR1'] = ‘some value';
envCopy[‘CUSTOM ENV VAR2'] = ‘some other value';

//使用process.env和自定義變量來(lái)執(zhí)行命令
exec(‘ls –la',{env: envCopy}, function(err,stdout,stderr){
    if(err){ throw err; }
    console.log(‘stdout:', stdout);
    console.log(‘stderr:',stderr);
}

上面例子,創(chuàng)建了一個(gè)用來(lái)保存環(huán)境變量的envCopy變量,它首先從process.env那里復(fù)制Node進(jìn)程的環(huán)境變量,然后又添加或替換了一些需要修改的環(huán)境變量,最后把envCopy作為環(huán)境變量參數(shù)傳遞給exec函數(shù)并執(zhí)行外部命令。

記住,環(huán)境變量是通過(guò)操作系統(tǒng)在進(jìn)程之間傳遞的,所有類(lèi)型的環(huán)境變量值都是以字符串的形式到達(dá)子進(jìn)程的。比如,如果父進(jìn)程將數(shù)字123作為一個(gè)環(huán)境變量,子進(jìn)程將會(huì)以字符串的形式接收“123”。

下面的例子,將在同一個(gè)目錄里建立2個(gè)Node腳本:parent.js和child.js,第一個(gè)腳本將會(huì)調(diào)用第二個(gè),下面我們來(lái)創(chuàng)建這兩個(gè)文件:

LISTING 8-3: 父進(jìn)程設(shè)置環(huán)境變量(chapter8/03_environment_number_parent.js)

復(fù)制代碼 代碼如下:

var exec = require('child_process').exec;

exec('node child.js', {env: {number: 123}}, function(err, stdout, stderr) {

if (err) { throw err; }

    console.log('stdout:\n', stdout);

    console.log('stderr:\n', stderr);

});

把這段代碼保存到parent.js,下面是子進(jìn)程的源碼,把它們保存到child.js(見(jiàn)例8-4)

例 8-4: 子進(jìn)程解析環(huán)境變量(chapter8/04_environment_number_child.js)

復(fù)制代碼 代碼如下:

var   number = process.env.number;

console.log(typeof(number)); // → "string"

number = parseInt(number, 10);

console.log(typeof(number)); // → "number"

當(dāng)你把這個(gè)文件保存為child.js后,就可以在這個(gè)目錄下運(yùn)行下面的命令:

復(fù)制代碼 代碼如下:

$ node parent.js

將會(huì)看到如下的輸出:

復(fù)制代碼 代碼如下:

sdtou:

string

number

stderr:

可以看到,盡管父進(jìn)程傳遞了一個(gè)數(shù)字型的環(huán)境變量,但是子進(jìn)程卻以字符串形式接收它(參見(jiàn)輸出的第二行),在第三行你把這個(gè)字符串解析成了一個(gè)數(shù)字。

生成子進(jìn)程

如你所見(jiàn),可以使用child_process.exec()函數(shù)來(lái)啟動(dòng)外部進(jìn)程,并在進(jìn)程結(jié)束的時(shí)候調(diào)用你的回調(diào)函數(shù),這樣用起來(lái)很簡(jiǎn)單,不過(guò)也有一些缺點(diǎn):

1.除了使用命令行參數(shù)和環(huán)境變量,使用exec()無(wú)法和子進(jìn)程通信
2.子進(jìn)程的輸出是被緩存的,因此你無(wú)法流化它,它可能會(huì)耗盡內(nèi)存

幸運(yùn)的是,Node的child_process模塊允許更細(xì)粒度的控制子進(jìn)程的啟動(dòng),停止,及其它常規(guī)操作。你可以在應(yīng)用程序里啟動(dòng)一個(gè)新的子進(jìn)程,Node提供一個(gè)雙向的通信通道,可以讓父進(jìn)程和子進(jìn)程相互收發(fā)字符串?dāng)?shù)據(jù)。父進(jìn)程還可以有些針對(duì)子進(jìn)程的管理操作,給子進(jìn)程發(fā)送信號(hào),以及強(qiáng)制關(guān)閉子進(jìn)程。

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

你可以使用child_process.spawn函數(shù)來(lái)創(chuàng)建一個(gè)新的子進(jìn)程,見(jiàn)例8-5:

例 8-5: 生成子進(jìn)程。 (chapter8/05_spawning_child.js)

復(fù)制代碼 代碼如下:

// 導(dǎo)入child_process模塊的spawn函數(shù)

var spawn = require('child_process').spawn;

// 生成用來(lái)執(zhí)行 "tail -f /var/log/system.log"命令的子進(jìn)程

var child = spawn('tail', ['-f', '/var/log/system.log']);

上面代碼生成了一個(gè)用來(lái)執(zhí)行tail命令的子進(jìn)程,并將“-f”和“/bar/log/system.log”作為參數(shù)。tail命令將會(huì)監(jiān)控/var/log/system.og文件(如果存在的話(huà)),然后將所有追加的新數(shù)據(jù)輸出到stdout標(biāo)準(zhǔn)輸出流。spawn函數(shù)返回一個(gè)ChildProcess對(duì)象,它是一個(gè)指針對(duì)象,封裝了真實(shí)進(jìn)程的訪(fǎng)問(wèn)接口。這個(gè)例子里我們把這個(gè)新的描述符賦值給一個(gè)叫做child的變量。

監(jiān)聽(tīng)來(lái)自子進(jìn)程的數(shù)據(jù)

任何包含stdout屬性的子進(jìn)程句柄,都會(huì)將子進(jìn)程的標(biāo)準(zhǔn)輸出stdout作為一個(gè)流對(duì)象,你可以在這個(gè)流對(duì)象上綁定data事件,這樣每當(dāng)有數(shù)據(jù)塊可用時(shí),就會(huì)調(diào)用對(duì)應(yīng)的回調(diào)函數(shù),見(jiàn)下面的例子:

復(fù)制代碼 代碼如下:

 //將子進(jìn)程的輸出打印到控制臺(tái)

child.stdout.on(‘data',function(data){

         console.log(‘tail output: ‘ + data);

});

每當(dāng)子進(jìn)程將數(shù)據(jù)輸出到標(biāo)準(zhǔn)輸出stdout時(shí),父進(jìn)程就會(huì)得到通知并把數(shù)據(jù)打印到控制臺(tái)。

除了標(biāo)準(zhǔn)輸出,進(jìn)程還有另外一個(gè)默認(rèn)輸出流:標(biāo)準(zhǔn)錯(cuò)誤流,通常用這個(gè)流來(lái)輸出錯(cuò)誤信息。

在這個(gè)例子里,如果/var/log/system.log文件不存在,tail進(jìn)程將會(huì)輸出類(lèi)似下面的消息:“/var/log/system.log:No such file or directory”,通過(guò)監(jiān)聽(tīng)stderr流,父進(jìn)程會(huì)在這種錯(cuò)誤發(fā)生時(shí)得到通知。

父進(jìn)程可以這樣監(jiān)聽(tīng)標(biāo)準(zhǔn)錯(cuò)誤流:

復(fù)制代碼 代碼如下:

child.stderr.on('data', function(data) {

    console.log('tail error output:', data);

});

 stderr屬性和stdout一樣,也是只讀流,每當(dāng)子進(jìn)程往標(biāo)準(zhǔn)錯(cuò)誤流里輸出數(shù)據(jù)時(shí),父進(jìn)程就會(huì)得到通知,并輸出數(shù)據(jù)。

發(fā)送數(shù)據(jù)到子進(jìn)程

除了從子進(jìn)程的輸出流里接收數(shù)據(jù),父進(jìn)程還可以通過(guò)childPoces.stdin屬性往子進(jìn)程的標(biāo)準(zhǔn)輸入里寫(xiě)入數(shù)據(jù),以此來(lái)往子進(jìn)程發(fā)送數(shù)據(jù)。

子進(jìn)程可以通過(guò)process.stdin只讀流來(lái)監(jiān)聽(tīng)標(biāo)準(zhǔn)輸入的數(shù)據(jù),但是注意你首先必須得恢復(fù)(resume)標(biāo)準(zhǔn)輸入流,因?yàn)樗J(rèn)處于暫停(paused)狀態(tài)。

例8-6將會(huì)創(chuàng)建一個(gè)包含如下功能的程序:

1.+1 應(yīng)用:一個(gè)簡(jiǎn)單的應(yīng)用程序,可以從標(biāo)準(zhǔn)輸入接收整型,然后相加,再把相加以后的結(jié)果輸出到標(biāo)準(zhǔn)輸出流。這個(gè)應(yīng)用作為一個(gè)簡(jiǎn)單的計(jì)算服務(wù), 把Node進(jìn)程模擬成一個(gè)可以執(zhí)行特定工作的外部服務(wù)。

2.測(cè)試+1應(yīng)用的客戶(hù)端,發(fā)送隨機(jī)整型,然后輸出結(jié)果。用來(lái)演示Node進(jìn)程如何生成一個(gè)子進(jìn)程然后讓它執(zhí)行特定的任務(wù)。

用下面例8-6的代碼創(chuàng)建一個(gè)名為plus_one.js的文件:

例 8-6: +1 應(yīng)用程序(chapter8/06_plus_one.js)

復(fù)制代碼 代碼如下:

// 恢復(fù)默認(rèn)是暫停狀態(tài)的標(biāo)準(zhǔn)輸入流
process.stdin.resume();
process.stdin.on('data', function(data) {
    var number;
    try {
        // 將輸入數(shù)據(jù)解析為整型
        number = parseInt(data.toString(), 10);
        // +1
        number += 1;
        // 輸出結(jié)果
        process.stdout.write(number + "\n");
    } catch(err) {
        process.stderr.write(err.message + "\n");
    }
});

上面代碼里,我們等待來(lái)自stdin標(biāo)準(zhǔn)輸入流的數(shù)據(jù),每當(dāng)有數(shù)據(jù)可用,就假設(shè)它是個(gè)整型并把它解析到一個(gè)整型變量里,然后加1,并把結(jié)果輸出到標(biāo)準(zhǔn)輸出流。

可以通過(guò)下面命令來(lái)運(yùn)行這個(gè)程序:

復(fù)制代碼 代碼如下:

    $ node plus_one.js

運(yùn)行后程序就開(kāi)始等待輸入,如果你輸入一個(gè)整數(shù)然后按回車(chē),就會(huì)看到一個(gè)被加1以后的數(shù)字被顯示到屏幕上。

可以通過(guò)按Ctrl-C來(lái)退出程序。

一個(gè)測(cè)試客戶(hù)端

現(xiàn)在你要?jiǎng)?chuàng)建一個(gè)Node進(jìn)程來(lái)使用前面的“+1應(yīng)用”提供的計(jì)算服務(wù)。

首先創(chuàng)建一個(gè)名為plus_one_test.js的文件,內(nèi)容見(jiàn)例8-7:

例 8-7: 測(cè)試+1應(yīng)用(chapter8/07_plus_one_test.js)

復(fù)制代碼 代碼如下:

var spawn = require('child_process').spawn;
// 生成一個(gè)子進(jìn)程來(lái)執(zhí)行+1應(yīng)用
var child = spawn('node', ['plus_one.js']);
// 每一秒調(diào)用一次函數(shù)
setInterval(function() {
    // Create a random number smaller than 10.000
    var number = Math.floor(Math.random() * 10000);
    // Send that number to the child process:
    child.stdin.write(number + "\n");
    // Get the response from the child process and print it:
    child.stdout.once('data', function(data) {
        console.log('child replied to ' + number + ' with: ' + data);
    });
}, 1000);
child.stderr.on('data', function(data) {
    process.stdout.write(data);
});

 從第一行到第四行啟動(dòng)了一個(gè)用來(lái)運(yùn)行“+1應(yīng)用”的子進(jìn)程,然后使用setInterval函數(shù)每秒鐘執(zhí)行一次下列操作:

1..新建一個(gè)小于10000的隨機(jī)數(shù)
2.將這個(gè)數(shù)字作為字符串傳遞給子進(jìn)程
3.等待子進(jìn)程回復(fù)一個(gè)字符串
4.因?yàn)槟阆朊看沃唤邮?個(gè)數(shù)字的計(jì)算結(jié)果,因此需要使用child.stdout.once而不是child.stdout.on。如果使用了后者,會(huì)每隔1秒注冊(cè)一個(gè)data事件的回調(diào)函數(shù),每個(gè)被注冊(cè)的回調(diào)函數(shù)都會(huì)在子進(jìn)程的stdout接收到數(shù)據(jù)時(shí)被執(zhí)行,這樣你會(huì)發(fā)現(xiàn)同一個(gè)計(jì)算結(jié)果會(huì)被輸出多次,這種行為顯然是錯(cuò)的。

在子進(jìn)程退出時(shí)接收通知

當(dāng)子進(jìn)程退出時(shí),exit事件會(huì)被觸發(fā)。例8-8展示了如何監(jiān)聽(tīng)它:

例 8-8: 監(jiān)聽(tīng)子進(jìn)程的退出事件 (chapter8/09_listen_child_exit.js)

復(fù)制代碼 代碼如下:

var spawn = require('child_process').spawn;
// 生成子進(jìn)程來(lái)執(zhí)行 "ls -la"命令
var child = spawn('ls', ['-la']);
child.stdout.on('data', function(data) {
    console.log('data from child: ' + data);
});

// 當(dāng)子進(jìn)程退出:
<strong>child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});</strong>

最后幾行加黑的代碼,父進(jìn)程使用子進(jìn)程的exit事件來(lái)監(jiān)聽(tīng)它的退出事件,當(dāng)事件發(fā)生時(shí),控制臺(tái)顯示相應(yīng)的輸出。子進(jìn)程的退出碼會(huì)被作為第一個(gè)參數(shù)傳遞給回調(diào)函數(shù)。有些程序使用一個(gè)非0的退出碼來(lái)代表某種失敗狀態(tài)。比如,如果你嘗試執(zhí)行命令“l(fā)s –al click filename.txt”,但是當(dāng)前目錄沒(méi)有這個(gè)文件,你就會(huì)得到一個(gè)值為1的退出碼,見(jiàn)例8-9:

例8-9:獲得子進(jìn)程的退出碼 (chapter8/10_child_exit_code.js)

復(fù)制代碼 代碼如下:

var spawn = require('child_process').spawn;
// 生成子進(jìn)程,執(zhí)行"ls does_not_exist.txt" 命令
var child = spawn('ls', ['does_not_exist.txt']);
// 當(dāng)子進(jìn)程退出
child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});

這個(gè)例子里,exit事件觸發(fā)了回調(diào)函數(shù),并把子進(jìn)程的退出碼作為第一個(gè)參數(shù)傳遞給它。如果子進(jìn)程是被信號(hào)殺死而導(dǎo)致的非正常退出,那么相應(yīng)的信號(hào)代碼會(huì)被當(dāng)作第二個(gè)參數(shù)傳遞給回調(diào)函數(shù),如例8-10:

LISTING 8-10: 獲得子進(jìn)程的退出信號(hào)(chapter8/11_child_exit_signal.js)

復(fù)制代碼 代碼如下:

var spawn = require('child_process').spawn;
// 生成子進(jìn)程,運(yùn)行"sleep 10"命令
var child = spawn('sleep', ['10']);
setTimeout(function() {
    child.kill();
}, 1000);
child.on('exit', function(code, signal) {
    if (code) {
        console.log('child process terminated with code ' + code);
    } else if (signal) {
        console.log('child process terminated because of signal ' + signal);
    }
});

這個(gè)例子里,啟動(dòng)一個(gè)子進(jìn)程來(lái)執(zhí)行sleep 10秒的操作,但是還沒(méi)到10秒就發(fā)送了一個(gè)SIGKILL信號(hào)給子進(jìn)程,這將會(huì)導(dǎo)致如下的輸出:

復(fù)制代碼 代碼如下:

child process terminated because of signal SIGTERM

發(fā)送信號(hào)并殺死進(jìn)程

在這部分,你將學(xué)習(xí)如何使用信號(hào)來(lái)管理子進(jìn)程。信號(hào)是父進(jìn)程用來(lái)跟子進(jìn)程通信,甚至殺死子進(jìn)程的一種簡(jiǎn)單方式。

不同的信號(hào)代碼代表不同的含義,有很多信號(hào),其中最常見(jiàn)的一些是用來(lái)殺死進(jìn)程的。如果一個(gè)進(jìn)程接收到一個(gè)它不知道如何處理的信號(hào),程序就會(huì)被異常中斷。有些信號(hào)會(huì)被子進(jìn)程處理,而有些只能由操作系統(tǒng)處理。

一般情況下,你可以使用child.kill方法來(lái)向子進(jìn)程發(fā)送一個(gè)信號(hào),默認(rèn)發(fā)送SIGTERM信號(hào):

復(fù)制代碼 代碼如下:

var spawn = require('child_process').spawn;
var child = spawn('sleep', ['10']);
setTimeout(function() {
    child.kill();
}, 1000);

還可以通過(guò)傳入一個(gè)標(biāo)識(shí)信號(hào)的字符串作為kill方法的唯一參數(shù),來(lái)發(fā)送某個(gè)特定的信號(hào):

復(fù)制代碼 代碼如下:

child.kill(‘SIGUSR2');

需要注意的是,雖然這個(gè)方法的名字叫kill,但是發(fā)送的信號(hào)并不一定會(huì)殺死子進(jìn)程。如果子進(jìn)程處理了信號(hào),默認(rèn)的信號(hào)行為就會(huì)被覆蓋。用Node寫(xiě)的子進(jìn)程可以像下面這樣重寫(xiě)信號(hào)處理器的定義:

復(fù)制代碼 代碼如下:

process.on('SIGUSR2', function() {
    console.log('Got   a SIGUSR2 signal');
});

現(xiàn)在,你定義了SIGUSR2的信號(hào)處理器,當(dāng)你的進(jìn)程再收到SIGUSR2信號(hào)的時(shí)候就不會(huì)被殺死,而是輸出“Got a SIGUSR2 signal”這句話(huà)。使用這種機(jī)制,你可以設(shè)計(jì)一種簡(jiǎn)單的方式來(lái)跟子進(jìn)程溝通甚至命令它。雖然不像使用標(biāo)準(zhǔn)輸入功能那么豐富,但是這方式要簡(jiǎn)單很多。

小結(jié)

這一章,學(xué)習(xí)了使用child_process.exec方法來(lái)執(zhí)行外部命令,這種方式可以不使用命令行參數(shù),而是通過(guò)定義環(huán)境變量的方式把參數(shù)傳遞給子進(jìn)程。

還學(xué)習(xí)了通過(guò)調(diào)用child_process.spawn方法生成子進(jìn)程的方式來(lái)調(diào)用外部命令,這種方式你可以使用輸入流,輸出流來(lái)跟子進(jìn)程通信,或者使用信號(hào)來(lái)跟子進(jìn)程通信以及殺死進(jìn)程。

相關(guān)文章

  • 安裝nvm并使用nvm安裝nodejs及配置環(huán)境變量的全過(guò)程

    安裝nvm并使用nvm安裝nodejs及配置環(huán)境變量的全過(guò)程

    有時(shí)候使用nvm管理node會(huì)發(fā)現(xiàn)無(wú)法使用node或npm,主要原因是環(huán)境變量沒(méi)有配置成功,下面這篇文章主要給大家介紹了關(guān)于安裝nvm并使用nvm安裝nodejs及配置環(huán)境變量的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • NodeJS學(xué)習(xí)筆記之Connect中間件應(yīng)用實(shí)例

    NodeJS學(xué)習(xí)筆記之Connect中間件應(yīng)用實(shí)例

    前面我們介紹了幾篇內(nèi)容的connect中間件的基礎(chǔ)知識(shí),今天我們來(lái)實(shí)例應(yīng)用一下,做個(gè)記事本的小應(yīng)用,希望大家能夠喜歡。
    2015-01-01
  • node.js中的emitter.emit方法使用說(shuō)明

    node.js中的emitter.emit方法使用說(shuō)明

    這篇文章主要介紹了node.js中的emitter.emit方法使用說(shuō)明,本文介紹了emitter.emit的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • NodeJs安裝npm包一直失敗的解決方法

    NodeJs安裝npm包一直失敗的解決方法

    本篇文章主要介紹了NodeJs安裝npm包一直失敗的解決方法。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-04-04
  • Egret引擎開(kāi)發(fā)指南之編譯項(xiàng)目

    Egret引擎開(kāi)發(fā)指南之編譯項(xiàng)目

    Egret框架是一個(gè)基于MIT開(kāi)源協(xié)議許可的永久免費(fèi)的項(xiàng)目!你可以在項(xiàng)目中隨意使用且修改它,并且擁有100%的控制權(quán)。你可以從Egret的Github網(wǎng)站獲取它的源代碼,從而了解和學(xué)習(xí)它的核心細(xì)節(jié)。Egret具有完善的文檔,并且易于上手學(xué)習(xí),可以讓你更容易專(zhuān)注于游戲本身的開(kāi)發(fā)
    2014-09-09
  • Node.JS在命令行中檢查Chrome瀏覽器是否安裝并打開(kāi)指定網(wǎng)址

    Node.JS在命令行中檢查Chrome瀏覽器是否安裝并打開(kāi)指定網(wǎng)址

    這篇文章主要介紹了Node.JS在命令行中檢查Chrome瀏覽器是否安裝,并打開(kāi)指定網(wǎng)址,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-05-05
  • 詳解如何利用Nodejs構(gòu)建多進(jìn)程應(yīng)用

    詳解如何利用Nodejs構(gòu)建多進(jìn)程應(yīng)用

    這篇文章主要為大家介紹了如何利用Nodejs構(gòu)建多進(jìn)程應(yīng)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 用npm install時(shí)報(bào)錯(cuò)node-sass npm ERR command failed問(wèn)題的解決方法

    用npm install時(shí)報(bào)錯(cuò)node-sass npm ERR command

    在用npm install時(shí)報(bào)錯(cuò)npm ERR! path D:…\node-sass和npm ERR! command failed 問(wèn)題,本文給大家介紹了如何解決這個(gè)問(wèn)題,文中通過(guò)圖文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • mongoose設(shè)置unique不生效問(wèn)題的解決及如何移除unique的限制

    mongoose設(shè)置unique不生效問(wèn)題的解決及如何移除unique的限制

    這篇文章主要給大家介紹了關(guān)于mongoose數(shù)據(jù)庫(kù)設(shè)置unique不生效問(wèn)題的解決方法,以及Mongoose如何移除unique限制的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • 使用node+vue.js實(shí)現(xiàn)SPA應(yīng)用

    使用node+vue.js實(shí)現(xiàn)SPA應(yīng)用

    這篇文章主要介紹了使用node+vue.js實(shí)現(xiàn)SPA應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2016-01-01

最新評(píng)論