Search This Blog

2016-02-09

Node js Child Process -exec, spawn and fork

There are two methods for running child processes under Node.js - exec and spawn.

child_process.exec(command, [options], callback)=>exectest.js
child_process.spawn(command, [args], [options])=>spawntest.js
There is an alternative of exec called spawn. Unlike exec it launches a new process and should be used if we expect long-time communication with the running command.

Exec() and spawn() both create processes, but they differ in what they return, spawn returns streams (stdout & stderr), while exec returns a buffer with a max size. Spawn() should be used when the process returns large amount of data.

 Another difference is that spawn() starts receiving the response as soon as the process starts executing, and exec() otherwise waits for the process to end and tries to return all the buffered data at once

 The fork method is a special case of the spawn() functionality, it only creates Node processes. Its signature is the following:

 child_process.fork(modulePath, [args], [options])=>forktest.js

Difference Between Spawn, fork and exec :

 require('child_process').spawn() starts sending back data from the child process in a stream as soon as the child process starts executing. When you run this command, it send a system command that will run on its own process rather than executing code within your node process. In this no new V8 instance will be created and only one copy of the node module will be active on the processor. It is used when you want the child process to return large amount of data to Node.

require('child_process').fork() is a special instance of spawn thats runs a new instance of the V8 engine. Which actually means you are creating multiple workers running on the same Node code base for different task.

require('child_process').exec() returns a buffer from the child process. The default buffer size is 200k. It is asynchronous, but it waits for the child process to end and tries to return all the buffered data at once. If your return data from the child process is greater than 200k then you will get maxBuffer exceeded.

ref:http://www.codingdefined.com/2014/08/difference-between-fork-spawn-and-exec.html

Example :

package.json:

{
  "name": "demochildprocess",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

exectest.js

const
fs = require('fs'),
process = require('child_process');

for(var i=0; i<3; i++) {
 var ls = process.exec('node worker.js '+i, function (error, stdout, stderr) {
    if (error) {
      console.log(error.stack);
      console.log('Error code: '+error.code);
      console.log('Signal received: '+error.signal);
    }
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);

  });

  ls.on('exit', function (code) {
    console.log('Child process exited with exit code '+code);
  });

}

/*Output:
Child process exited with exit code 0
stdout: Process 0 at work
stderr:

Child process exited with exit code 0
stdout: Process 1 at work
stderr:

Child process exited with exit code 0
stdout: Process 2 at work
stderr:*/

spawntest.js

const
 fs = require('fs'),
 process = require('child_process');

/*Create 10 worker process*/
for(var i=0; i<3; i++) {
 var ls = process.spawn('node', ['worker.js', i]);

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

 ls.stderr.on('data', function (data) {
   console.log('stderr: ' + data);
 });

 ls.on('close', function (code) {
   console.log('child process exited with code ' + code);
 });
}

/*
stdout: Process 0 at work

stdout: Process 1 at work

child process exited with code 0
child process exited with code 0
stdout: Process 2 at work

child process exited with code 0
*/

forktest.js

const
 fs = require('fs'),
 process = require('child_process');
   

for(var i=0; i <3; i++) {
 var ls = process.fork("worker.js", [i]);

 ls.on('close', function (code) {
   console.log('child process exited with code ' + code);
 });
}

/*
Process 0 at work
child process exited with code 0
Process 1 at work
Process 2 at work
child process exited with code 0
child process exited with code 0

*/


No comments: