Nodejs(Google Chrome)中的事件循环使用了什么逻辑流模型



很长一段时间以来,我一直认为Chrome和Node.js中使用的事件循环实现(libuv?(使用线程。但后来我读了一篇关于Java中轻量级线程的文章,其中指出:

。。。不是为每个并发任务(和阻塞任务(创建线程,而是由一个专用线程(称为事件循环(查看在非响应模型中分配给线程的所有任务,并在同一CPU核心上处理每个任务。

还有《计算机系统》一书。并发应用程序一章中的程序员观点指出,现代操作系统提供了三种基本的构建方法并发程序(实现逻辑流的3种方法(:

  • 流程。使用这种方法,每个逻辑控制流都是由内核调度和维护的进程。自从进程有单独的虚拟地址空间,流希望相互交流必须使用某种明确的方式进程间通信(IPC(机制。

  • I/O多路复用。这是一种并发编程形式,其中应用程序在单个过程的上下文。逻辑流建模为状态主程序从状态显式转换到的机器状态作为数据到达文件描述符的结果。自程序是一个单独的进程,所有流共享相同的地址空间。

  • 线程。线程是在单个进程的上下文中运行并由内核调度的逻辑流。你可以想到线程作为其他两种方法的混合,由类似内核的进程流并共享相同的虚拟地址空间如I/O多路复用流。

所以现在我想知道事件循环是否属于I/O multiplexing逻辑流并且不使用线程?

我与V8团队无关,但我会尽力回答这个问题。

首先,V8本身与事件循环无关。Node.js使用libuv来实现事件循环以及操作系统特定API(网络、FS等(的抽象。事件循环本身在单个操作系统线程上运行,大多数网络操作都在基于该线程的I/O复用API(epoll、kqueue等(上执行

但是libuv也有一个线程池来运行阻塞I/O(例如FS、DNS查找(和CPU密集型操作(例如加密(。线程池通过内存中的队列与事件循环集成(通信(。当一个阻塞/CPU密集型任务必须启动时,它会被放入队列,稍后其中一个线程开始处理它

因此,Node.js使用了多种方法来实现用户操作之间的并发:操作系统线程(BTW,包括worker_threads模块(、I/O复用、多进程(带有child_process模块(。

V8也为自己的目的使用了许多操作系统线程(比如GC(,但它不需要知道事件循环或为操作系统级API提供任何抽象。它的目标是,好吧,执行给定的JS代码,并提供一个坚实的嵌入式API,这样你就可以用它来构建浏览器/运行时

最新更新