2

我有一个主进程,这个 fork 一个子进程。这孩子做一些计算。在孩子代码的某个时刻,我想向父母询问一些数据。这个请求是高度动态的,此时我想等待这个请求的回答/响应。但是我如何等待 process.send() 或者是否可以向 .send() 添加回调函数?

我试图将我的问题分解为一个简单的例子。在我的示例中,高度动态的值是 worker 中的 randomval。我知道任务

var c = process.send({msg:'get_c',randomval:Math.floor((Math.random()*10)+1)});

不能工作。但我不知道如何描述这个问题。

main.js

var childProcessCalc = require('child_process').fork(__dirname + '/worker');
childProcessCalc.send({msgtype:'docalc'});

childProcessCalc.on('message',function(msg){
if(msg.msg === 'pi')
{
    console.log("Pi"+msg.pi+" by c="+msg.c);
}
else if(msg.msg === 'get_c')
{
    console.log('child wants c');
    childProcessCalc.send({msgtype:'your_c',c:1000000*msg.randomval});
}
});

childProcessCalc.on('exit',function(){
    console.log('main:the childProzess has exit!')
});  

worker.js

process.on('message', function(msg){

if(msg.msgtype == 'docalc') {
    //Here is my Problem, how to wait for the message thats the response for
    //exactly this send / randomval, or how to add a callback to send
    var c = process.send({msg:'get_c',randomval:Math.floor((Math.random()*10)+1)});

    var Pi=0;
    var n=1;
    for (var i=0;i<=c;i++)
    {
        Pi=Pi+(4/n)-(4/(n+2))
        n=n+4
    }
    process.send({msg:'pi',pi:Pi,c:c})
}
else if(msg.msgtype === 'your_c')
{
    console.log('parent hase sendc='+msg.c);
}

});
4

2 回答 2

1

我有一个解决我的问题的方法,它对我来说效果很好,但是因为我在 nodejs 上很新,如果这是最好的方法,我现在还不是。它的感觉就像一个开销。

简而言之,我做了什么:我添加了一个对象,该对象存储了一个随机回调标识符和回调函数,如果我们得到对给定回调标识符的响应,则必须调用该回调函数。当我现在从工作人员调用 send() 时,我将标识符发送到主进程,主进程在他完成后将这个标识符发回。所以我可以在我的回调变量(dynamicMassages)中查找回调函数来调用和执行它。

main2.js

var childProcessCalc = require('child_process').fork(__dirname + '/worker2');
childProcessCalc.send({msgtype:'docalc'});

childProcessCalc.send({msgtype:'docalc'});

childProcessCalc.on('message',function(msg){
if(msg.msg === 'pi')
{
    console.log("Pi"+msg.pi+" by c="+msg.c);
}
else if(msg.msg === 'get_c')
{
    console.log('child wants c');
    childProcessCalc.send({msgtype:'your_c',callbackid:msg.callbackid, c:1000000*msg.randomval});
}
});

childProcessCalc.on('exit',function(){
    console.log('main:the childProzess has exit!')
});

worker2.js

var dynamicMassages = {};

process.on('message', function(msg){

var getRandomId = function(){
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
    {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }

    if(dynamicMassages[text] === undefined)
    {
        return text;
    }
    else
    {
        return getRandomId();
    }
};

if(msg.msgtype == 'docalc') {
    var randomId = getRandomId();
    var callbackFnc = function(c){
        var Pi=0;
        var n=1;
        for (var i=0;i<=c;i++)
        {
            Pi=Pi+(4/n)-(4/(n+2))
            n=n+4
        }
        console.log("callbackFnc For:"+randomId);
        process.send({msg:'pi',pi:Pi,c:c})
        delete dynamicMassages[randomId];
    };

    dynamicMassages[randomId] = callbackFnc;//callbackFnc;
    process.send({msg:'get_c',callbackid: randomId, randomval:Math.floor((Math.random()*10)+1)});


}
else if(msg.msgtype === 'your_c')
{
    console.log('parent hase sendc='+msg.c+' for callbackId '+msg.callbackid);
    if(msg.callbackid !== undefined)
    {
        dynamicMassages[msg.callbackid](msg.c);
    }
}

});

如果您想以同样的方式发表评论,请发表评论。

于 2013-09-27T04:25:19.870 回答
0

我建议您使用消息总线,要么是成熟的高级解决方案,例如RabbitMQ,要么是更小的解决方案,例如axon

基本上,你想做的是进程间通信,我会尽量坚持既定的协议和标准,避免滚动你自己的解决方案。由于 RabbitMQ 建立在 AMQP 之上,我猜你可以称它为standard

于 2013-09-29T11:50:07.567 回答