Anonymous
Anonymous

Reputation: 557

Getting the correct process id from child processes

So, I'm spawning a few processes and trying to figure out the PID of the process when it gets some data, here's my code:

var mod_child_process = require('child_process');
var mod_events        = require('events');

for (var i=0; i<3; ++i)
{
    var childProcess;

    childProcess = mod_child_process.spawn('HandShake.exe', ['N:192.168.200.250:3001:1', 'Q:TIME']);    

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

}

It always returns a single pid

stdout (78748): 18/7/13 15:46:26
stdout (78748): 18/7/13 15:46:26
stdout (78748): 18/7/13 15:46:27

Thanks in advance.

Upvotes: 7

Views: 12606

Answers (3)

Hafthor
Hafthor

Reputation: 16896

Fun fact: by just changing var to let inside the for initializer you avoid this problem!

Note, however, this only works if the variable is within the scope of the loop. Declare it before the loop and you get the same results as var.

Upvotes: 1

Jay
Jay

Reputation: 19857

You're running into a scoping issue with the variable childProcess. Variables in JavaScript are function scoped. Because of this, the variable isn't exclusive to the loop.

Simplified example of code acting how you have it:

for (var i = 0; i < 3; ++i) {
    var someNumber = i;

    setTimeout(function() {
        console.log(someNumber);
    }, 100);
}

outputs: 2, 2, 2

And the fix:

for (var i = 0; i < 3; ++i) {
    (function() {
        var someNumber = i;

        setTimeout(function() {
            console.log(someNumber);
        }, 100);
    })();
}

You want to wrap your logic in a closure so that the variable childProcess exists with that scope. The above code outputs the expected 0, 1, 2

Upvotes: 9

user568109
user568109

Reputation: 47993

Looks like a closure problem. Pass the loop variable to a function so that scope is not affected.

var mod_child_process = require('child_process');
var mod_events        = require('events');

for (var i=0; i<3; ++i)
{
    var childProcess;
    childProcess = mod_child_process.spawn('cmd.exe');  
    displayid(childProcess);  
}

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

Output is

stdout (368): Microsoft Windows [Version 6.2.9200]
stdout (20268): Microsoft Windows [Version 6.2.9200]
stdout (15728): Microsoft Windows [Version 6.2.9200]

Without it

stdout (10964): Microsoft Windows [Version 6.2.9200]
stdout (10964): Microsoft Windows [Version 6.2.9200]
stdout (10964): Microsoft Windows [Version 6.2.9200]

Upvotes: 3

Related Questions