Node.js 借助 libuv 的能力,利用队列和线程池实现了非阻塞 I/O。
首先 Google V8 引擎负责单线程解释执行 JavaScript 代码,在遇到网络或者磁盘 I/O 请求后,运行模式如下:
Node.js 的核心技术有两个:V8 提供的天然单线程排队执行机制,和 libuv 提供的跨越 Linux、Windows、macOS 三个系统的非阻塞 I/O 能力。
Go 语言之所以快,主要是因为其并发模型、垃圾回收、编译优化、内存管理和标准库等方面都是完全面向“高性能网络编程”这个需求设计的。
Go 在语言 runtime 层面实现了完善的用户态协程调度,并且将以 epoll 为代表的 I/O 多路复用贯彻到了网络的方方面面,编码难度低,很容易就能写出高性能的代码。具体来说,Go 语言在设计上有如下几个优势:
传统的进程/线程之所以慢,是因为当某个 CPU 核心这个图灵机从执行一个线程切换为执行下一个线程的时候,由于会出现用户态->内核态->用户态的切换(即上下文切换),导致了对内存的读写。Go 在语言 runtime 层面实现了一个可以在用户态的单个线程的内部进行自主管理的协程调度机制,让一个协程的代码执行完之后,不需要进行上下文切换,无需读写内存,在操作系统看来,这个线程没有任何的变化,依然在按照顺序执行一个又一个指令。这个机制使得 CPU 时间片得到了最大程度的利用,是 Goroutine 高性能最大的贡献者。
详细地说,Goroutine 拥有如下这些专门的设计来达成超高性能:
go
即可创建一个 Goroutine。这使得开发者可以轻松地编写高并发的代码,而不需要关心复杂的线程同步和互斥问题。📙 高并发的哲学原理 《Philosophical Principles of High Concurrency》
Copyright © 2023 吕文翰