大津です。

解決して何よりです。

ついでにですが今回の件は違う面からみるとある意味教育的な
ところがありまして、現象として

「今回の whiile(true) {} などのように node のプロセスCPU を食い
つぶす処理を行うと、見た目 Node がハングしたようになる。」

ということだったんじゃないかと思います。

これは昨年話題となった "Node.js is Cancer"
http://teddziuba.com/2011/10/node-js-is-cancer.html で

「フィボナッチ数を計算して出力するだけなのに Node.js はこんな
に遅くて使えない。」

といったことと同じで、

「プロセスのCPUを使う重い処理は(イベントループに影響を与えるので)
Node には向かない」

といわれる所以です。(先のフィボナッチ処理も process.nextTick() の再帰
処理で実装すると非常に高速になりました。)

でも、重い処理だけど iterative にできない Node で使うにはどうしたら?
というケースもあるかもしれません。
そんな時は処理を外出しするのも一つの方法です。

今回の例を cluster で外出しするとこんな感じです。重い処理を worker に
やらせるので master の方は signal を受けて処理するだけになります。

node-v0.8 では Cluster 関連の API、イベントが多く追加され、これまで以上
に柔軟な worker 制御が可能になります。近日のリリースを楽しみにして下さい。

------------------------------------------------------------
var cluster = require('cluster');

if (cluster.isMaster) {

var worker = cluster.fork();

process.on('SIGUSR1', function (){
process.kill(worker.pid);
console.log("usr1.");
process.exit(100);
});
process.on('SIGINT', function (){
process.kill(worker.pid);
console.log("interrupted.");
process.exit(200);
});
process.on('exit', function (){
console.log("exit.");
});
cluster.on('death', function(w) {
process.exit(10);
});

} else {
var c = 0;
while(true){
console.log("foo" + c);
c++;
// if (c == 10000) {
// process.exit(10);
// }
}
}

(2012/04/27 0:55), Taro YACHI wrote:
> やちです。
>
> 提示していただいたcodeでこちらの思い通りの動作になりました。
> 実行context?をnodeに戻さないといけないのは、考えてみればあたりまえなんですけど、気がつきませんでした。
>
> ありがとうございました。
>
> 2012/4/26 Shigeki Ohtsu <oh...@iij.ad.jp>:
>> 大津です。
>>
>> while(true) {} が終了しないので次のイベントループに回らないからだと思い
>> ます。
>> (正確には tp.js の読み込みで1回分イベントループが回っていますが)
>>
>> while(true) で回すのではなく process.nextTick() で再帰的にカウンター
>> を回せば、おそらくシグナルウォッチャーのコールバックを受けることが
>> できるはずです。
>>
>> 以下を試してみたらいかがでしょうか?
>>
>> -------------------------------------------------------
>> process.on('SIGUSR1', function (){
>>
>> console.log("usr1.");
>> process.exit(100);
>> });
>> process.on('SIGINT', function (){
>> console.log("interrupted.");
>> process.exit(200);
>> });
>> process.on('exit', function (){
>> console.log("exit.");
>> });
>>
>> var c = 0;
>> function output() {
>> process.nextTick(function() {
>> console.log("foo" + c);
>> c++;
>> // if (c == 10000) {
>> // process.exit(10);
>> // }
>> output();
>> });
>> }
>> output();
>>
>> -------------------------------------------------------
>>
>>
>> (2012/04/26 23:23), Taro YACHI wrote:
>>> やちといいます。
>>>
>>> 環境:
>>> FreeBSD 8.2R p3
>>> node v0.6.14
>>>
>>> SIGINTとかのsignalをうけとりたいと思い、下記のようなcodeを書きました。
>>>
>>> tp.js
>>> -------------------------------------------------------
>>> process.on('SIGUSR1', function (){
>>>       console.log("usr1.");
>>>       process.exit(100);
>>> });
>>> process.on('SIGINT', function (){
>>>       console.log("interrupted.");
>>>       process.exit(200);
>>> });
>>> process.on('exit', function (){
>>>       console.log("exit.");
>>> });
>>>
>>> var c = 0;
>>> while(true){
>>>       console.log("foo" + c);
>>>       c++;
>>> //    if (c == 10000) {
>>> //            process.exit(10);
>>> //    }
>>> }
>>> -------------------------------------------------------
>>>
>>> で、$ node tp.js として、実行。他のterminalから$ killall -USR1 node としても、割り込みにより
>>> console.logでの文言を出力したり、process.exit()によって止めたり出来ません。また、nodeを実行したterminalで
>>> CTRL-Cをしても止まりません。
>>> SIGINTのprocess.on()を削ると、CTRL-Cで止まるので、trapは出来ているような気がしています。が、
>>> console.llogしている文言はいずれも出力されません。
>>>
>>> なにか、指摘をお願いします。
>>>

メールによる返信