如何处理 Node.js 中的子线程?
Node.js 是一种单线程语言,它在后台将多个线程用于某些任务作为 I/O 调用,但它不会向开发人员公开子线程。
但是,如果我们真的需要与我们的主单线程进程并行执行一些工作,node.js 为我们提供了解决方法。
节点中的子进程: child_process 模块使节点能够通过访问操作系统命令来运行子进程。
示例:文件名:parallelProcess.js
javascript
// Do any work in parallel to main
// event loop or main process
console.log('Child Process Starts')
setTimeout(() => {
console.log('Data processed')
}, 5000)
javascript
const { fork } = require('child_process');
// Fork another process
const child_process = fork('./parallelProcess.js');
// Data we may need to send to the child process
const data = {}
console.log('Before process')
// Send the data to forked process
child_process.send({ data }, function(){
console.log('Sending data')
});
// Listen to forked process
child_process.on('close', (result) => {
console.log('Child process terminated and returned');
});
console.log('After process')
javascript
const {Worker, isMainThread, parentPort}
= require('worker_threads');
if (isMainThread) {
// Main code, only executed for main thread
const worker = new Worker(__filename, {
workerData: {}
});
worker.on('message', (m) => console.log(
'Thread send message:', m));
worker.on('error', () => console.log('Error'));
worker.on('exit', () => {
console.log('Worker exit')
});
} else {
// Worker thread code, only execute
// for working thread.
setTimeout(() => {
parentPort.postMessage('Hello World!');
}, 3000)
}
文件名:main.js
javascript
const { fork } = require('child_process');
// Fork another process
const child_process = fork('./parallelProcess.js');
// Data we may need to send to the child process
const data = {}
console.log('Before process')
// Send the data to forked process
child_process.send({ data }, function(){
console.log('Sending data')
});
// Listen to forked process
child_process.on('close', (result) => {
console.log('Child process terminated and returned');
});
console.log('After process')
输出:
Before process
After process
Child Process Starts
Data processed
Child process terminated and returned
工作线程worker_threads 模块允许使用并行执行 JavaScript 的线程。 Worker 的线程对于执行 CPU 密集型 JavaScript 操作很有用。它们对 I/O 密集型工作没有多大帮助,使用 Node.js 内置的异步 I/O 操作可以更好地完成这些工作。
例子:
javascript
const {Worker, isMainThread, parentPort}
= require('worker_threads');
if (isMainThread) {
// Main code, only executed for main thread
const worker = new Worker(__filename, {
workerData: {}
});
worker.on('message', (m) => console.log(
'Thread send message:', m));
worker.on('error', () => console.log('Error'));
worker.on('exit', () => {
console.log('Worker exit')
});
} else {
// Worker thread code, only execute
// for working thread.
setTimeout(() => {
parentPort.postMessage('Hello World!');
}, 3000)
}
输出:
Thread send message: Hello World!
Worker exit
另一方面,进程有自己的内存空间,线程使用共享内存空间。线程是进程的一部分。由于 worker_threads 在同一进程中创建新线程,因此需要更少的资源。
参考:
https://nodejs.org/api/child_process.html
https://nodejs.org/api/worker_threads.html