加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Node.js多线程完全指南

发布时间:2019-03-29 23:34:32 所属栏目:建站 来源:疯狂的技术宅
导读:很多人都想知道单线程的 Node.js 怎么能与多线程后端竞争。考虑到其所谓的单线程特性,许多大公司选择 Node 作为其后端似乎违反直觉。要想知道原因,必须理解其单线程的真正含义。 JavaScript 的设计非常适合在网上做比较简单的事情,比如验证表单,或者说

为了更好地描述我们将要做的事情,下面我们来创建一个由八个 thread worker 组成的工作池:

  1. const pool = new WorkerPool(path.join(__dirname, './test-worker.js'), 8); 

如果你熟悉限制并发操作,那么你在这里看到的逻辑几乎相同,只是一个不同的用例。

如上面的代码片段所示,我们把指向 worker 的路径和要生成的 worker 数量传给了 WorkerPool 的构造函数。

  1. export class WorkerPool<T, N> {  
  2.  private queue: QueueItem<T, N>[] = [];  
  3.  private workersById: { [key: number]: Worker } = {};  
  4.  private activeWorkersById: { [key: number]: boolean } = {};  
  5.  public constructor(public workerPath: string, public numberOfThreads: number) {  
  6.    this.init();  
  7.  }  

这里还有其他一些属性,如 workersById 和 activeWorkersById,我们可以分别保存现有的 worker 和当前正在运行的 worker 的 ID。还有 queue,我们可以使用以下结构来保存对象:

  1. type QueueCallback<N> = (err: any, result?: N) => void;  
  2. interface QueueItem<T, N> {  
  3.  callback: QueueCallback<N>;  
  4.  getData: () => T;  

callback 只是默认的节点回调,第一个参数是错误,第二个参数是可能的结果。 getData 是传递给工作池 .run() 方法的函数(如下所述),一旦项目开始处理就会被调用。 getData 函数返回的数据将传给工作线程。

在 .init() 方法中,我们创建了 worker 并将它们保存在以下状态中:

  1. private init() {  
  2.   if (this.numberOfThreads < 1) {  
  3.     return null;  
  4.   }  
  5.   for (let i = 0; i < this.numberOfThreads; i += 1) {  
  6.     const worker = new Worker(this.workerPath);  
  7.     this.workersById[i] = worker;  
  8.     this.activeWorkersById[i] = false;  
  9.   }  

为避免无限循环,我们首先要确保线程数 > 1。然后创建有效的 worker 数,并将它们的索引保存在 workersById 状态。我们在 activeWorkersById 状态中保存了它们当前是否正在运行的信息,默认情况下该状态始终为false。

现在我们必须实现前面提到的 .run() 方法来设置一个 worker 可用的任务。

  1. public run(getData: () => T) {  
  2.   return new Promise<N>((resolve, reject) => {  
  3.     const availableWorkerId = this.getInactiveWorkerId();  
  4.     const queueItem: QueueItem<T, N> = {  
  5.       getData,  
  6.       callback: (error, result) => {  
  7.         if (error) {  
  8.           return reject(error);  
  9.         }  
  10. return resolve(result);  
  11.       },  
  12.     };  
  13.     if (availableWorkerId === -1) {  
  14.       this.queue.push(queueItem);  
  15.       return null;  
  16.     }  
  17.     this.runWorker(availableWorkerId, queueItem);  
  18.   });  

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读