Node has multiple threads, but JavaScript running on v8 is single threaded. Node's child_process module is used to create child processes, and we can make full use of the CPU through child processes. example:
The code copy is as follows:
var fork = require('child_process').fork;
// Get the CPU number of the current machine
var cpus = require('os').cpus();
for (var i = 0; i < cpus.length; i++) {
// Generate a new process
fork('./worker.js');
}
Here are some ways to create processes including fork:
1.spawn(command, [args], [options]), start a new process to execute command command, args is a command line parameter
2.exec(command, [options], callback), start a new process to execute command command, callback is used to obtain standard input, standard output, and error information at the end of the process.
3.execFile(file, [args], [options], [callback]), starts a new process to execute the executable file. Callback is used to obtain standard input, standard output, and error information at the end of the process.
4.fork(modulePath, [args], [options]), start a new process to execute a JavaScript file module, and the Node child process is created at this time.
Node Interprocess Communication
Parent process
The code copy is as follows:
// parent.js
var fork = require('child_process').fork;
// fork returns child process object n
var n = fork('./child.js');
// Handle event message
n.on('message', function(m) {
// Receive a message sent by the child process
console.log('got message: ' + m);
});
// Send a message to the child process
n.send({hello: 'world'});
Subprocess
The code copy is as follows:
// child.js
// Handle event message
process.on('message', function(m) {
console.log('got message: ' + m);
});
// The send method exists for sending messages to the parent process.
process.send({foo: 'bar'});
It should be noted that the send method here is synchronous, so it is not recommended to send large amounts of data (you can use pipe instead, see http://nodejs.org/api/all.html#child_process_child_process_spawn_command_args_options for details).
In special cases, the cmd attribute value in the message contains the NODE_ prefix (for example: {cmd: 'NODE_foo'} message), then this message will not be submitted to the message event (but the internalMessage event), and they are used internally by Node.
The prototype of the send method is:
The code copy is as follows:
send(message, [sendHandle])
Here, sendHandle (handle) can be used to send:
1.net.Native, native C++ TCP socket or pipeline
2.net.Server, TCP server
3.net.Socket, TCP socket
4.dgram.Native, native C++ UDP socket
5.dgram.Socket, UDP socket
send When sending sendHandle, it is not (and cannot) to directly send JavaScript objects, but to send a file descriptor (eventually sent as a JSON string). Other processes can restore the corresponding object through this file descriptor.
Now look at an example:
Parent process
The code copy is as follows:
// parent.js
var fork = require('child_process').fork;
var n = fork('./child.js');
var server = require('net').createServer();
server.listen(7000, function() {
// Send TCP server to child process
n.send('server', server);
}).on('connection', function() {
console.log('connection - parent');
});
Subprocess
The code copy is as follows:
process.on('message', function(m, h) {
if (m === 'server') {
h.on('connection', function() {
console.log('connection - child');
});
}
});
Accessing this program via port 7000 can result in the output as connection parent or connection child. Here, the child process and the parent process listen to port 7000 at the same time. Generally speaking, multiple processes listening to the same port will cause an EADDRINUSE exception. In this case, two different processes use the same file descriptor, and the Node underlying layer sets the SO_REUSEADDR option on the socket when listening to the port, which allows this socket to be reused among different processes. When multiple processes listen to the same port, the file descriptor can only be used by one process at the same time, and these processes use sockets preemptively.
cluster module
A new cluster module has been added to v0.8 in Node, through which the cluster module can easily build a group of processes listening to the same port on a physical machine. example:
The code copy is as follows:
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
// Check whether the process is a master process
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; ++i)
// Generate a new worker process (only the master process can be called)
cluster.fork();
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' die');
});
} else {
http.createServer(function(req, res) {
res.writeHead(200);
res.end('hello world/n');
}).listen(8000);
}
We call the listen method in the worker process, and the listening request will be passed to the master process. If the master process already has a server listening to meet the requirements of the worker process, the handle of this server will be passed to the worker. If it does not exist, the master process will create one and then pass the handle to the worker process.
More detailed documentation about cluster: http://www.nodejs.org/api/cluster.html