Node.js多线程完全指南(4)
在工作线程中:
parentPort 前面提到的 MessagePort 实例,用于与父线程通信。 threadId 分配给 worker 的唯一标识符。 现在我们知道了技术细节,接下来实现一些东西并在实践中检验学到的知识。 实现 setTimeout setTimeout 是一个无限循环,顾名思义,用来检测程序运行时间是否超时。它在循环中检查起始时间与给定毫秒数之和是否小于实际日期。
这个特定的实现产生一个线程,然后执行它的代码,最后在完成后退出。 接下来实现使用这个 worker 的代码。首先创建一个状态,用它来跟踪生成的 worker:
然后时负责创建 worker 并将其保存到状态的函数:
首先,我们使用 UUID 包为 worker 创建一个唯一的标识符,然后用先前定义的函数 runWorker 来获取 worker。我们还向 worker 传入一个回调函数,一旦 worker 发送了数据就会被触发。最后,把 worker 保存在状态中并返回 id。 在回调函数中,我们必须检查该 worker 是否仍然存在于该状态中,因为有可能会 cancelTimeout(),这将会把它删除。如果确实存在,就把它从状态中删除,并调用传给 setTimeout 函数的 callback。 cancelTimeout 函数使用 .terminate() 方法强制 worker 退出,并从该状态中删除该这个worker:
如果你有兴趣,我也实现了 setInterval,代码在这里,但因为它对线程什么都没做(我们重用setTimeout的代码),所以我决定不在这里进行解释。 我已经创建了一个短小的测试代码,目的是检查这种方法与原生方法的不同之处。你可以在这里找到代码。这些是结果:
我们可以看到 setTimeout 有一点延迟 - 大约40ms - 这时 worker 被创建时的消耗。平均 CPU 成本也略高,但没什么难以忍受的(CPU 成本是整个过程持续时间内 CPU 使用率的平均值)。 如果我们可以重用 worker,就能够降低延迟和 CPU 使用率,这就是要实现工作池的原因。 实现工作池 如上所述,工作池是给定数量的被事先创建的 worker,他们保持空闲并监听 message 事件。一旦 message 事件被触发,他们就会开始工作并发回结果。 (编辑:ASP站长网) |