哪个对node.js上的并发任务更好?纤维?网络工作者?还是线程?


111

我前一段时间偶然发现了node.js,非常喜欢。但是很快我发现它严重缺乏执行CPU密集型任务的能力。因此,我开始使用Google搜索,并找到了解决这些问题的答案:光纤,Webworkers和线程(go-a-gogo)。现在使用哪个是一个混乱的问题,肯定需要使用其中的一个-毕竟,拥有一台只擅长IO且无其他优点的服务器的目的是什么?需要建议!

更新:

我在想一种落后的方法。只是需要建议。现在,我想到的是:让我们来一些线程(使用thread_a_gogo或webworkers)。现在,当我们需要更多它们时,我们可以创建更多。但是在创建过程中会有一些限制。(不是系统暗示的,但可能是因为开销)。现在,当我们超过限制时,我们可以派生一个新节点,并开始在该节点上创建线程。这样,它可以一直持续到我们达到某个极限(毕竟,过程也有很大的开销)。当达到此限制时,我们开始排队任务。每当线程空闲时,就会为它分配一个新任务。这样,它可以顺利进行。

所以,这就是我的想法。这个主意好吗?我对所有这些过程和线程东西还是有点陌生​​,所以没有任何专业知识。请分享您的意见。

谢谢。:)


请注意:Worker是浏览器规范,而不是Javascript功能。
FredTheWebGuy 2013年

好吧,我明白了。我的问题是关于node.js-服务器代码,而不是关于客户端!
Parth Thakkar

只是澄清一下-我看到最初的问题是关于NodeJs中的Webworkers的,这是不可能的-NodeJs使用“线程”。但是,周围有一个NodeJS模块,该模块允许在NodeJs运行时内使用WebWorker语法。
FredTheWebGuy 2013年

Answers:


330

Node具有完全不同的范例,一旦正确地捕获它,就更容易看到这种解决问题的不同方式。在Node应用程序(1)中,您永远不需要多个线程,因为您执行相同操作的方式不同。您创建多个流程;但这与Apache Web Server的Prefork mpm的做法非常不同。

现在,让我们认为我们只有一个CPU内核,我们将开发一个应用程序(以Node的方式)来完成一些工作。我们的工作是处理逐个字节运行其内容的大文件。对于我们的软件而言,最好的方法是从文件的开头开始工作,然后逐字节地跟踪文件的结尾。

-嘿,哈桑,我想你是我祖父时代的一所新手或老学校!!!为什么不创建一些线程并使它更快呢?

-哦,我们只有一个CPU核心。

- 所以呢?创建一些线程人,使其更快!

-它不是那样工作的。如果创建线程,我将使其变慢。因为我将在系统之间增加很多开销,以便在线程之间进行切换,因此尝试给它们以公平的时间,并在进程内部尝试在这些线程之间进行通信。除了所有这些事实之外,我还必须考虑如何将一个工作分解为多个可以并行完成的工作。

-好的,我知道你很穷。让我们使用我的计算机,它具有32核!

-哇,亲爱的朋友,你真棒,非常感谢。我很感激!

然后我们回去工作。现在我们有32个cpu内核,这要归功于我们丰富的朋友。我们必须遵守的规则刚刚改变。现在我们要利用我们得到的所有财富。

要使用多个内核,我们需要找到一种方法来将我们的工作分成可以并行处理的部分。如果不是Node,我们将为此使用线程。32个线程,每个cpu核心一个。但是,由于我们有Node,所以我们将创建32个Node进程。

线程可以很好地替代Node进程,甚至是更好的方法。但是仅在已经定义了工作并且可以完全控制其处理方式的特定工作中。除此之外,对于工作以外来的其他问题,我们无法控制,我们想尽快回答,Node的方法无疑是优越的。

-嘿,哈桑,你还在单线程工作吗?你怎么了,伙计?我刚刚为您提供了您想要的。你没有借口了。创建线程,使其运行更快。

-我将工作分为几部分,每个过程将并行处理其中的一部分。

-为什么不创建线程?

-对不起,我认为它不可用。如果需要,可以带计算机吗?

-不好,我很酷,我只是不明白为什么你不使用线程?

-谢谢您的电脑。:)我已经将工作分为几部分,并创建了并行处理这些部分的流程。所有CPU内核将得到充分利用。我可以用线程而不是进程来完成;但是Node有这种方式,我的老板Parth Thakkar希望我使用Node。

-好的,让我知道您是否需要另一台计算机。:p

如果我创建的不是33个进程,而是33个进程,则操作系统的调度程序将暂停一个线程,启动另一个线程,在某些周期后暂停它,然后再次启动另一个线程...这是不必要的开销。我不想要这个。实际上,在具有32个内核的系统上,我什至不想创建精确的32个进程,所以31个更好。因为不仅仅我的应用程序可以在该系统上运行。为其他事情留一点空间可能会很好,尤其是如果我们有32个房间。

我相信我们现在在同一页上,关于充分利用处理器来执行CPU密集型任务

-嗯,哈桑(Hasan),很抱歉对你有些嘲笑。我相信我现在对您的了解更好。但是我仍然需要解释一下:关于运行数百个线程的所有嗡嗡声是什么?我到处都读到,创建线程和创建线程要比派生进程快得多?您派生了进程而不是线程,并且您认为它是使用Node获得的最高性能。那么,Node不适合这种工作吗?

-不用担心,我也很酷。每个人都说这些话,所以我想我已经习惯了。

-那么?节点对此不好吗?

-即使线程也可以很好,Node对此非常有用。至于线程/进程创建的开销;在重复很多的事情上,每一毫秒都很重要。但是,我仅创建32个进程,这将花费很少的时间。它只会发生一次。不会有任何区别。

-那么我什么时候要创建数千个线程?

-您永远不想创建数千个线程。但是,在执行来自外部的工作的系统上,例如处理HTTP请求的Web服务器。如果您为每个请求使用一个线程,则将创建很多线程,其中很多。

-节点不一样吗?对?

- 对,就是这样。这是Node真正发挥作用的地方。就像线程比进程轻得多,函数调用比线程轻得多。节点调用函数,而不是创建线程。在Web服务器的示例中,每个传入请求都导致一个函数调用。

-嗯,很有趣;但是,如果不使用多个线程,则只能同时运行一个函数。当许多请求同时到达Web服务器时,该如何工作?

-您对函数的运行方式完全正确,一次只运行一次,永远不会并行运行两个。我的意思是在一个过程中,一次只运行一个范围的代码。OS Scheduler不会出现并暂停此功能并切换到另一个功能,除非它暂停该进程以给另一个进程(而不是我们进程中的另一个线程)留出时间。(2)

-那么一个进程如何一次处理两个请求?

-只要我们的系统具有足够的资源(RAM,网络等),一个进程就可以一次处理数万个请求。这些功能的运行方式是关键区别。

-嗯,我现在应该兴奋吗?

-也许:)节点在队列上运行循环。我们的工作在这个队列中,即我们开始处理传入请求的呼叫。这里最重要的一点是我们设计函数运行的方式。在开始可接受的工作量之后,我们快速结束函数,而不是开始处理请求并使调用者等待完成任务。当我们需要等待另一个组件完成一些工作并返回一个值,而不是等待该值时,我们只需完成函数即可将其余工作添加到队列中。

-听起来太复杂了吗?

-不,我听起来可能很复杂;但是系统本身非常简单,非常合理。

现在,我要停止引用这两个开发人员之间的对话,并在最后一个有关这些功能如何工作的快速示例之后结束我的回答。

这样,我们正在执行OS Scheduler通常会执行的操作。我们暂停工作,并让其他函数调用(如多线程环境中的其他线程)运行,直到再次轮到我们为止。这比将工作留给OS Scheduler更好,后者试图给系统上的每个线程仅时间。我们知道我们的工作要比OS Scheduler好得多,并且应该在应该停止时停止。

下面是一个简单的示例,其中我们打开一个文件并读取它以对数据进行一些处理。

同步方式:

Open File
Repeat This:    
    Read Some
    Do the work

异步方式:

Open File and Do this when it is ready: // Our function returns
    Repeat this:
        Read Some and when it is ready: // Returns again
            Do some work

如您所见,我们的功能要求系统打开文件,而不等待文件被打开。文件准备好后,通过提供后续步骤来完成自身。当我们返回时,Node在队列上运行其他函数调用。运行完所有功能后,事件循环移至下一轮。

总之,Node具有与多线程开发完全不同的范例。但这并不意味着它缺少东西。对于同步作业(我们可以确定处理的顺序和方式),它与多线程并行性一样有效。对于诸如请求服务器之类的来自外部的作业,它简直是上乘。


(1)除非使用其他语言(例如C / C ++)构建库,否则在这种情况下,您仍然不会创建用于划分作业的线程。对于这种工作,您有两个线程,一个线程将继续与Node通讯,而另一个线程则进行实际工作。

(2)实际上,由于我在第一个脚注中提到的相同原因,每个Node进程都有多个线程。但是,这绝不是1000个线程做类似的工作。这些额外的线程用于接受IO事件并处理进程间消息传递。

更新(作为对评论中一个好的问题的答复)

@Mark,感谢您的建设性批评。在Node的范例中,除非将队列中的所有其他调用都设计为一个接一个地运行,否则永远不要有需要花费太长时间处理的函数。如果计算任务比较繁琐,那么如果我们完整地看一下图片,就会发现这不是“我们应该使用线程还是进程?”的问题。但是有一个问题:“如何将这些任务均衡地划分为子任务,以便可以使用系统上的多个CPU内核并行运行它们?” 假设我们将在具有8个核心的系统上处理400个视频文件。如果我们想一次处理一个文件,那么我们需要一个能够处理同一文件的不同部分的系统,在这种情况下,也许多线程单进程系统将更易于构建并且效率更高。我们仍然可以通过运行多个进程并在需要状态共享/通信时在它们之间传递消息来使用Node。如前所述,使用Node的多进程方法是以及此类任务中的多线程方法;但不止于此。再次,正如我之前所讲的,Node的亮点是当这些任务作为来自多个源的输入作为系统输入时,因为与每个连接线程或每个连接进程相比,在Node中同时保持多个连接要轻得多系统。

至于setTimeout(...,0)通话;有时,在耗时的任务期间要休息一下,以允许队列中的呼叫可以共享其处理量。以不同方式划分任务可以使您免于这些任务;但这并不是真正的hack,它只是事件队列的工作方式。同样,process.nextTick为此目的使用更好,因为当您使用时setTimeout,有必要计算和检查经过的时间,而process.nextTick这正是我们真正想要的:“嘿,任务,回到队列的末端,您已经使用了您的份额! ”


9
惊人!该死的惊人!我喜欢您回答这个问题的方式!:)
Parth Thakkar

48
当然:)我真的不敢相信会有非常卑鄙的人在投票否决这个答案!发问者称其为“该死的惊人!” 看到这本书之后,有本书的作者为我提供了写作;但是那里有一些天才对它投反对票。您为什么不分享自己的聪明才智并对此发表评论,而不是卑鄙而卑鄙地投票呢?为什么好东西会这么打扰您?您为什么要阻止有用的东西传播给可以真正从中受益的其他人?
hasanyasin 2012年

9
这不是一个完全公平的答案。对于计算量大的任务呢,我们不能“迅速结束”函数调用呢?我相信有人setTimeout(...,0)为此使用了一些技巧,但是在这种情况下使用单独的线程肯定会更好?
mpen

3
@hasanyasin这是我到目前为止找到的关于节点的最好的解释!:)
Venemo

7
@Mark通常,如果这在计算上很昂贵,则有一些供踏步/过程工作者使用的选项/模块...通常,对于这些类型的事情,我使用消息队列,并有一个工作者进程来处理某个任务。从队列中抽出时间来完成该任务。这也允许扩展到多个服务器。沿着这些思路,Substack有很多针对配置和扩展的模块,您可以查看。
Tracker1 2013年

34

(2016年更新:Web Worker正在使用io.js-Node.js分支 Node.js v7-参见下文。)

(2017年更新:Web worker 不再使用 Node.js v7或v8-参见下文。)

(2018年更新:Web Worker 正在进入Node.js Node v10.5.0-参见下文。)

一些澄清

阅读了以上答案后,我想指出的是,Web工作人员中没有任何东西与JavaScript的哲学(特别是关于并发性)有悖。(如果有的话,WHATWG甚至不会讨论它,更不用说在浏览器中实现了)。

您可以将Web Worker看作是可以异步访问的轻量级微服务。没有共享状态。不存在锁定问题。没有阻塞。无需同步。就像当您从Node程序中使用RESTful服务时一样,您不必担心它现在是“多线程的”,因为RESTful服务与您自己的事件循环不在同一线程中。它只是您异步访问的单独服务,这很重要。

网络工作者也是如此。这是一个与在完全独立的上下文中运行的代码进行通信的API,由于严格的异步,非阻塞API,无论是在不同线程,不同进程,不同cgroup,区域,容器还是不同机器中,它都是完全无关的,所有数据均按值传递。

事实上,Web工作者从概念上讲是Node的理想之选,因为它-很多人不知道-偶然大量使用线程,并且实际上“除了代码之外,所有其他事情并行运行”-请参阅:

但是网络工作者甚至不需要使用线程来实现。只要使用Web Worker API,您就可以在云中使用进程,绿色线程甚至RESTful服务。带有按值调用语义的消息传递API的全部好处在于,底层实现几乎是无关紧要的,因为并发模型的细节不会被公开。

单线程事件循环非常适合I / O绑定操作。对于受CPU限制的操作,尤其是长时间运行的操作,它的效果不佳。为此,我们需要产生更多的进程或使用线程。以可移植的方式管理子进程和进程间通信可能非常困难,并且通常被视为对简单任务的矫kill过正,而使用线程意味着处理很难正确处理的锁和同步问题。

通常建议将长时间运行的CPU绑定操作划分为较小的任务(类似于我对“加速setInterval ”的回答的“原始答案”部分中的示例),但它并不总是实用的,并且不会更多地使用一个CPU内核。

我写这篇文章是为了澄清评论,这些评论基本上是在说Web worker是为浏览器而不是服务器创建的(忘记了JavaScript中几乎所有内容都可以这么说)。

节点模块

应该有几个模块可以将Web Worker添加到Node:

我没有使用过它们,但有两点相关的快速观察:截至2015年3月,node-webworker的最新更新是4年前,node-webworker-threads的最新更新是一个月前。另外我在node-webworker-threads用法示例中看到,您可以使用函数而不是文件名作为Worker构造函数的参数,如果使用共享内存的线程实现该函数,可能会引起细微的问题(除非函数仅用于其.toString()方法,否则将在其他环境中编译,在这种情况下可能会很好-我必须更深入地研究它,仅在这里分享我的观点)。

如果还有其他在Node中实现Web Worker API的相关项目,请发表评论。

更新1

在撰写本文时,我还不知道,但是在我撰写此答案的前一天,我偶然将Web Workers添加到了io.js中

io.js是Node.js的一个分支-请参阅:为什么io.js决定派遣Node.js,以获取更多信息,InfoWorld采访了Mikeal Rogers。)

它不仅证明了这样的观点,即在Web工作人员中没有什么与通用JavaScript的哲学相抵触,尤其是在并发方面,尤其是Node方面,这还可能导致Web工作人员成为io之类的服务器端JavaScript的一等公民。 js(将来可能还有Node.js),就像所有现代浏览器中的客户端JavaScript一样。

更新2

在Update 1和我的推文中,我指的是io.js拉取请求#1159 ,该请求现在重定向到 7月8日关闭的Node PR#1159,并替换为Node PR#2133-它仍处于打开状态。在这些拉取请求下进行了一些讨论,这些讨论可能会提供有关io.js / Node.js中Web工作者状态的更多最新信息。

更新3

最新信息 -感谢NiCk Newman在评论中发布它:有工作人员: Petka Antonov从2015年9月6日提交的初始实现,可以在此树中下载并试用 。有关详细信息,请参见NiCk Newman的评论

更新4

截至2016年5月,对仍未公开的PR#2133的最新评论-工人:最初实施的时间为3个月。5月30日,马修斯·莫雷拉(Matheus Moreira)要求我在下面的评论中发布此答案的更新,他在PR评论中询问此功能的当前状态

公关讨论中的第一个答案令人怀疑,但后来本·诺德维斯 Ben Noordhuis)写道:“将其以一种或多种形状合并在我的v7任务清单上”。

所有其他评论似乎都支持,并且到2016年7月,似乎应该在计划于2016年10月发布的下一版本的Node 7.0中使用Web Workers(不一定以确切的PR形式)。

感谢Matheus Moreira在评论中指出并恢复了GitHub上的讨论。

更新5

截至2016年7月,npm上几乎没有以前可用的模块-有关相关模块的完整列表,请在npm上搜索工作人员,网络工作人员等。如果有什么特别有用的东西或对您不起作用,请发布一个评论。

更新6

截至2017年1月,网络工作者不太可能被合并到Node.js中。

拉动请求#2133 worker: Petka Antonov于2015年7月8日开始实施,最终由Ben Noordhuis于2016年12月11日关闭,他评论说“多线程支持增加了太多新的失败模式,以至于没有足够的收益”,还可以使用共享内存和更有效的序列化等更传统的方式来实现这一目标。”

有关更多信息,请参阅GitHub上PR 2133的注释。

再次感谢Matheus Moreira在评论中指出这一点。

更新6

我很高兴地宣布,几天前,即20186月,网络工作者出现在Node v10.5.0中,这是一个带有--experimental-worker标志激活的实验功能。

有关更多信息,请参见:

🎉🎉🎉最后!我可以对3岁的Stack Overflow答案进行第7次更新,在该答案中,我认为对单线程Web线程进行线程化并不违反Node哲学,只是这次是我们终于做到了!😜👍


1
@NiCkNewman谢谢。我看到io.js中的原始请求请求现在已经关闭,并被另一个请求所取代-在GitHub上的请求请求注释中进行了一些讨论,也许您可​​以在其中找到一些信息。请参阅:我的答案中的Update 2。
rsp 2015年

1
是的,看起来他们只是解决了最后一个libuv问题。我想知道何时可以使用该模块。不能等!感谢您为我们提供最新信息〜编辑:刚刚初始化:github.com/petkaantonov/io.js/commit/…我们走了,它来了!
NiCk Newman

1
是的,它是直播。(尚未正式实现),但是您可以在此处下载源代码:github.com/petkaantonov/io.js/tree/…并进行编译(如果您想对其进行测试!)我现在做吧〜
尼克·纽曼

1
@NiCkNewman感谢您提供新信息-我将其添加到了答案中。
rsp

1
您能否向我们介绍Node.js workers实现的状态?PR#2133中的最新评论来自2月;开发人员显然遇到了问题,没有评论表明已解决。
Matheus Moreira

8

我来自古老的思想流派,在那儿我们使用多线程来使软件快速运行。在过去的三年中,我一直在使用Node.js及其强大的支持者。正如hasanyasin详细解释的那样,节点如何工作以及异步功能的概念。但是,让我在这里添加一些内容。

在过去只有单核和较低时钟速度的时代,我们尝试了各种方法来使软件快速且并行地工作。在DOS时代,我们通常一次运行一个程序。在Windows中,我们开始一起运行多个应用程序(进程)。诸如抢占式和非抢占式(或合作式)之类的概念都经过测试。我们现在知道,抢先是单核计算机上更好的多处理任务的答案。随之而来的是流程/任务和上下文切换的概念。比线程的概念进一步减轻了进程上下文切换的负担。轻巧的螺纹替代了新工艺的产生。

因此,无论喜欢与否,或者不发出信号,或者没有多核或单核,您的进程将被操作系统抢占时间。

Nodejs是一个单一的进程,并提供异步机制。在这里,我们在事件循环中等待任务完成的同时,将作业分派给底层OS执行任务。一旦我们从操作系统获得绿色信号,我们便会执行我们需要做的一切。现在,从某种意义上说,这是合作/非抢占式多任务处理,因此我们绝不应该在很长的一段时间内阻塞事件循环,否则我们将很快降级我们的应用程序。
因此,如果有一项任务本质上是阻塞的或非常耗时,我们将不得不将其扩展到操作系统和线程的先发制人世界。在libuv文档中有很好的例子。此外,如果您进一步阅读文档,则会发现FileI / O是在node.js的线程中处理的

因此,首先是我们软件的设计。其次,上下文切换始终在发生,无论他们告诉您什么。线程在那里并且仍然在那里是有原因的,原因是它们在随后的进程之间切换的速度更快。

在node.js中,它包含所有c ++和线程。节点提供了c ++方式来扩展其功能,并通过在必须使用线程的地方使用线程来进一步加快速度,即阻塞任务,例如从源读取到源写入,大数据分析等。

我知道hasanyasin答案是被接受的答案,但是对我来说,无论您说什么或如何将它们隐藏在脚本后面,线程都将存在,其次,没有人只是为了提高速度而将线程分解成线程,这主要是为了阻止任务。而且线程位于Node.js的后端,因此在完全扑朔迷离之前,多线程是正确的。此外,线程不同于进程,并且每个内核具有节点进程的限制并不完全适用于线程数,线程就像进程的子任务。实际上,线程不会显示在Windows任务管理器或linux top命令中。再一次,它们的重量更轻,然后加工


异步代码不是什么巨大的创新(事实上,我们已经有几十年了),并且多线程并不是要取代的一些过时的技术。它们是权衡不同的不同工具,实际上它们甚至可以很好地结合在一起。每次您运行节点群集时,实际上您都在运行多个“线程”(在这种情况下,进程可以运行,但是使用线程可以实现相同的过程,甚至更轻量)。或者采用Erlang或Go,它们可以运行数千个绿色线程...
Hejazzman

我认为我们缺少的主要观点是,操作系统下的过程将始终以抢占方式进行以提供公平。同样,对于多处理器,您可以执行实际的并行代码,但即使那样,您也将抢占。OS在某些过程中还执行异步工作。
凌晨

4

我不确定在这种情况下网络工作者是否相关,他们是客户端技术(在浏览器中运行),而node.js在服务器上运行。据我所知,光纤也处于阻塞状态,即它们是自愿的多任务处理,因此您可以使用它们,但应该通过自己管理上下文切换yield。线程实际上可能是您所需要的,但我不知道它们在node.js中的成熟程度。


3
仅出于您的信息考虑,webworkers已(部分)在node.js上进行了改编。并作为node-workers包装提供。看看这个:github.com/cramforce/node-worker
Parth Thakkar,

很高兴知道,谢谢。但是,文档非常稀缺,我不知道它是在单独的线程,进程中运行还是在同一个进程中运行,而且我没有时间深入研究代码,所以我不知道它是否会为您的情况服务。
lanzz,2012年

@ParthThakkar:该项目已经3年没有被触及(发布时为2),也没有超过0.0.1。
mpen

@Mark:对此我无知的原因是我还不是专业的程序员。哎呀,我什至没有上大学。我仍然是一名高中生,除了管理学校作业外,他还在继续阅读编程知识。因此,我不可能遥不可及关于所有此类问题的知识。我刚刚发布了我所知道的...
Parth Thakkar,2013年

@Mark:尽管很高兴向您指出项目的历史。这些事情将在我将来的答复中处理!!:)
塔斯·塔卡

3

worker_threads已被实施并运送到国旗后面node@10.5.0。它仍然是一个初始实现,需要做更多的工作才能使其在将来的版本中更有效。值得一试node


2

在许多Node开发人员看来,Node最好的部分之一实际上是其单线程性质。线程由于共享资源而带来了很多困难,而Node通过不做非阻塞IO便什么也不能完全避免。

这并不是说Node 仅限于一个线程。只是获得线程并发的方法与您要查找的方法不同。处理线程的标准方法是Node本身附带的集群模块。与在代码中手动处理线程相比,这是一种更简单的线程处理方法。

为了处理代码中的异步编程(如避免嵌套的回调金字塔),Fibers库中的[Future]组件是不错的选择。我还建议您检查一下基于光纤的Asyncblock。光纤很不错,因为它们允许您通过复制堆栈来隐藏回调,然后根据需要在单线程的堆栈之间跳转。在为您带来好处的同时,节省了实际线程的麻烦。不利之处在于,使用Fibers时,堆栈跟踪可能会有些怪异,但还算不错。

如果您不需要担心异步问题,而只是对进行大量处理而没有阻塞感兴趣,那么只需要不时一次简单地调用process.nextTick(callback)就可以了。


好吧,您关于群集的建议是我最初考虑的。但是问题在于它们的开销-每次派生一个新进程(〜30ms,10MB)时,都必须初始化一个v8新实例。因此,您不能创建很多。这直接取自于节点文档:这些子节点(关于child_processes)仍然是V8的全新实例。假设每个新节点至少需要30ms的启动时间和10mb的内存。也就是说,您无法创建成千上万的文件。
塔斯卡·帕克

1
这正是集群的想法。每个cpu核心运行一名工作人员。再有可能是不必要的了。即使是CPU密集型任务也可以使用异步样式很好地工作。但是,如果您确实需要成熟的线程,则可能应该考虑完全迁移到另一个服务器后端。
genericdave

1

也许有关您正在执行的任务的更多信息会有所帮助。您为什么需要(如您在对genericdave的回答的评论中所提到的)需要创建成千上万个?在Node中执行此类操作的通常方法是启动一个工作进程(使用fork或其他方法),该进程始终运行,并且可以使用消息进行通信。换句话说,不要在每次需要执行正在执行的任务时都启动新的工作程序,而只是向已运行的工作程序发送消息并在完成后得到响应。老实说,我看不出启动数千个实际线程也不会非常有效,因为您仍然受到CPU的限制。

现在,在说完所有这些之后,我最近在Hook.io上做了很多工作,对于将这种卸载任务分担到其他进程中来说,它似乎工作得很好,也许它可以完成您需要的工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.