1、创建进程
方式一 child_process
child_process 提供四种方法来创建子进程:
- spawn() – 适用于长时间运行的进程
- exec() – 适用于短时间执行的 shell 命令
- execFile() – 直接运行可执行文件
- fork() – 专门用于创建 Node.js 子进程,并支持进程间通信(IPC)
使用 spawn() 创建子进程示例:
1 | const { spawn } = require('child_process'); |
使用 fork() 创建子进程示例:1
2
3
4
5
6
7
8
9
10
11
12
13// 主进程文件
const { fork } = require('child_process');
const child = fork('child.js');
child.on('message', (msg) => {
console.log(`主进程收到消息: ${msg}`);
});
child.send('Hello from parent');
// 子进程child.js 文件
process.on('message', (msg) => {
console.log(`子进程收到消息: ${msg}`);
process.send('Hello from child');
});
方式二 cluster
cluster 模块用于创建多进程来共享服务器端口
示例:创建多个 Worker 进程:
1 | const cluster = require('cluster'); |
特点:
- cluster.isMaster 确保只有主进程负责管理 Worker。
- cluster.fork() 创建多个 Worker(默认和 CPU 核心数一致)。
- 各个 Worker 进程共享同一端口,提高性能。
child_process 和 cluster 区别
维度 | child_process | cluster |
---|---|---|
主要用途 | 创建独立的子进程,适用于任务分工 | 创建多个工作进程(Worker),用于负载均衡 |
进程关系 | 父进程可以创建多个子进程,但默认不共享端口 | Master 进程自动管理多个 Worker 进程,Worker 共享端口 |
进程间通信 (IPC) | 需要手动使用 process.send() 进行数据传输 | 内部自动处理进程间通信 |
端口管理 | 每个子进程通常绑定不同的端口 | 所有 Worker 进程可以共享同一个端口 |
应用场景 | 任务处理(如爬虫、数据计算) | 多进程 Web 服务器,提高并发能力 |
代码复杂度 | 需要手动管理进程和通信 | 更简洁,适用于创建多进程服务器 |
2、创建线程
Node.js 的主线程是单线程的,但可以使用 Worker Threads 在后台创建多个线程执行计算密集型任务,而不阻塞主线程。
方式一 worker_threads
从 Node.js 10 开始,worker_threads 允许在 Node.js 中使用真正的多线程
1 | const { Worker, isMainThread, parentPort } = require('worker_threads'); |
方式二 poolifier 线程池
poolifier 是一个线程池管理库,可以优化 Worker 线程的管理。
1 | const { DynamicPool } = require('poolifier'); |
优点:
- poolifier 提供线程池机制,避免频繁创建和销毁 Worker 线程,提高性能。
3、process 和 threads 区别
方案 | 模块 | 适用场景 | 优势 | 劣势 |
---|---|---|---|---|
多进程 | child_process / cluster | 处理多个请求,利用多核 CPU | 进程隔离,不影响主线程 | 进程开销大,占用更多内存 |
多线程 | worker_threads | 计算密集型任务,如加密、压缩 | 共享内存,开销小 | 线程同步需要管理 |
- 如果是 I/O 密集型任务(如 Web 服务器),建议使用 cluster 创建多个进程处理请求。
- 如果是 CPU 密集型任务(如数学计算),建议使用 worker_threads 进行多线程计算。