gpt4 book ai didi

javascript - 是否将Node.js视为具有工作线程的多线程?

转载 作者:行者123 更新时间:2023-12-01 15:55:25 25 4
gpt4 key购买 nike

我一生都认为Node.js和JavaScript是单线程语言。 Node.js不能很好地处理CPU密集型任务,但由于其单线程性质,因此它是轻量级的。多线程对CPU密集型任务很有用,因为您可以将任务委派给不同的线程,但它会为竞争条件创造条件,这可能会变得很复杂。
然后是工作线程,告诉我 Node 现在可以生成名为“工作线程”的线程以通过CPU密集型任务,从而不会阻塞JavaScript堆栈。如果人们借助工作线程的力量实际上可以将其称为多线程,为什么人们将JavaScript称为永久定义的单线程呢?还是JavaScript确实是永久性的单线程,但是借助工作线程的强大功能,一个进程能够拥有多个JavaScript线程,而这些线程仍然表现为单线程?

Node.js uses two kinds of threads: a main thread handled by event loop and several auxiliary threads in the worker pool.


另外,我读过的这篇文章说的是上面的陈述。这听起来好像JavaScript实际上一直在使用多个不同的线程。人们为什么称JavaScript为单线程?

最佳答案

This makes it sound like JavaScript was actually using multiple different threads the entire time. Why are people calling JavaScript single threaded?


Node.js中的编程模型是一个单线程事件循环,可以访问异步操作,这些操作使用 native 代码为某些操作(磁盘I/O,网络,计时器,某些加密操作等)实现异步行为。
另外,请记住,此编程模型不是JavaScript语言本身的产品。它是如何将JavaScript作为事件驱动的实现方式部署在诸如Node.js和浏览器之类的流行环境中的产品。
内部存在用于执行某些异步操作(例如文件I/O或某些加密操作)的 native 代码线程池的事实并没有改变编程模型是单线程事件循环的事实。线程池就是如何通过JavaScript实现耗时任务的实现以使其具有异步接口(interface)的方法。这是一个实现细节,它不会从单个线程的事件循环模型中更改JavaScript编程模型。
同样,您现在可以实际创建WorkerThreads的事实并没有真正改变主编程模型,这是因为WorkerThreads在具有单独的事件循环的单独的JavaScript VM中运行并且不共享常规变量。因此,无论是否使用WorkerThreads,您都仍然需要为事件驱动的非阻塞系统设计代码。
WorkerThreads确实允许您卸载一些耗时的任务,以使它们脱离主事件循环,以使该主事件循环保持更高的响应速度,这在某些情况下是一个非常有用的选择。但是,整体模型不会改变。例如,所有联网仍是事件驱动的且非阻塞的,异步的。因此,仅因为我们拥有WorkerThreads,这并不意味着您现在就可以像现在有时在Java中那样使用JavaScript编程网络,为每个新的传入请求使用单独的线程。 JavaScript模型的那部分完全没有改变。如果您在Node.js中拥有HTTP服务器,则该服务器仍一次只能接收一个传入请求,并且直到该先前的传入请求将控制权返回到事件循环之前,它才开始处理下一个传入请求。
另外,您应该知道,Node.js中WorkerThreads的当前实现相当繁重。创建WorkerThread会启动一个新的JavaScript VM,初始化一个新的全局上下文,建立一个新的堆,启动一个新的垃圾收集器,分配一些内存,等等。虽然在某些情况下有用,但是这些WorkerThreads很多,比操作系统级别的线程重得多。我认为它们几乎就像迷你子进程一样,但是它们的优点是它们可以在WorkerThreads之间或主线程与WorkerThreads之间使用您无法使用实际子进程的SharedMemory。

Or is JavaScript indeed permanently single threaded, but with the power of worker threads, a process is able to have multiple threads of JavaScript, which still behave single thread?


首先,JavaScript语言规范中没有固有的要求单线程的东西。单线程编程模型是如何在诸如Node.js和浏览器之类的流行编程环境中实现JavaScript语言的产物。因此,在谈论单线程性时,您应该谈论的是编程环境(例如Node.js),而不是语言本身。
在Node.js中,一个进程现在可以具有多个JavaScript线程(使用WorkerThreads)。它们独立运行,因此您可以在多个线程中同时并行运行JavaScript。为了避免线程同步的许多陷阱,WorkerThreads在单独的VM中运行,除了非常仔细地分配和控制的SharedMemory缓冲区外,不共享对其他WorkerThreads或主线程的变量的访问。通常,WorkerThreads将使用通过事件循环运行的消息传递与主线程进行通信(因此,以这种方式在所有JavaScript线程上强制执行同步级别)。消息不会以抢先方式在线程之间传递-这些通信消息会流过事件循环,并且必须像Node.js中的任何其他异步操作一样等待处理。
这是使用WorkerThreads的示例实现。我正在编写一个测试程序,其工作是对 Activity 进行数十亿次模拟,并记录所有结果的统计信息,以查看结果的随机性。模拟的某些部分涉及一些加密操作,这些操作在CPU上非常耗时。在我的第一代代码中,我运行的迭代次数较少,但很显然,所需的数十亿次迭代将花费许多小时才能运行。
通过测试和测量,我能够找出代码的哪些部分使用了最多的CPU,然后创建了一个WorkerThread池(8个工作线程),可以将更多耗时的工作传递给它们,然后它们可以在其中工作。平行。这将运行模拟的总时间减少了7倍。
现在,我也可以为此使用子进程,但是它们的效率会降低,因为我需要在主线程和workerThread之间传递大型数据缓冲区(workerThread在该缓冲区中处理数据),并且这样做很多使用SharedArrayBuffer进行此操作比在父进程和子进程之间传递数据(这将涉及复制数据而不是共享数据)更有效。

关于javascript - 是否将Node.js视为具有工作线程的多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63224356/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com