Node v0.5.0ででたforkを試してみる

require('child_process').forkはWorkerと同じAPIを使っているぽいです。

fork APIの定義

var worker = require('child_process').fork(modulePath, arguments, options);
  • argumentsh: 配列で、生成された子プロセス側ではprocess.argvで受け取ることができます。
  • options: documentではcustomFdsの上書きに使うとあります。

こんな感じで使います

  • main.js
var cp = require('child_process')
, cnum = 10
, workers = []
// メッセージ転送関数
, postOffice = function(m){
		console.log('id ('+m.from+') says ['+m.body+'] to id ('+m.to+')');
		workers[m.to].send({from: m.from, body: m.body});
};

// 子プロセスを立ち上げて、ついでにmessageイベントにハンドラをバインドする
for(var i = 0; i < cnum; i++){
		var child = cp.fork(__dirname + '/worker.js', [i, cnum]);
		child.on('message', postOffice);
		workers.push(child);
}

// 一回目のメッセージ
setTimeout(function(){
		var cid = 0|Math.random() * cnum;
		workers[cid].send({from: 'parent', body: 'hello'});
}, 1000)
  • woker.js
var id = process.argv[2]
, brosnum = process.argv[3];
process.on('message', function(m){
		setTimeout(function(){
				var cid = 0|Math.random() * brosnum;
				process.send({from: id, to: cid, body: 'hello'});
		}, 0|Math.random() * 1000);
});

これで、main.jsを実行すると

$ node hoge.js 
id (3) says [hello] to id (9)
id (9) says [hello] to id (9)
id (9) says [hello] to id (4)
id (4) says [hello] to id (0)
id (0) says [hello] to id (2)
id (2) says [hello] to id (4)
id (4) says [hello] to id (6)
id (6) says [hello] to id (2)
id (2) says [hello] to id (2)

こんな感じでプロセス同士のやりとりをすることができます。

でも、親が介在(postOffice)するとか、いけてないですよね

って思ったので、なんとか、子プロセスのリストを子プロセスたちに渡せないかと試行錯誤したんですが

  • × global
  • × module
  • × argumentsではオブジェクトが渡されているようなんですが、子プロセスのリストを渡すと、うまくないです。
  • x messageで子プロセスのリスト渡す。

sendはJSON.stringifyをしているので、うまく動かないです > <

あと、おまけに

These child Nodes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node. That is, you cannot create many thousands of them.

何千個もworkerあげんなよ!って書いてあります。