不同语言对于线程的实现可能大相径庭
- 由于操作系统提供了创建线程的API ,因此部分语言会直接调用该API 来创建线程,最终程序内的线程数和该程序占用的操作系统线程数相等,称之为 1:1 线程模型,例如Rust采用的就是这种线程模型
- 还有些语言在内部实现了自己的线程模型(绿色线程、协程),程序内部的M个线程最后会以某种映射方式使用N个操作系统线程去运行,称之为 M:N 线程模型,其中M和N并没有特定的彼此限制关系,比如Go语言
- 还有些语言使用了 Actor 模型,基于消息传递进行并发,例如 Erlang 语言
总之,每一种模型都有利有弊,需要权衡。而 Rust 在设计时考虑的权衡就是 运行时( Runtime )。出于 Rust 的系统级使用场景,且要保证调用 C 时的极致性能,它最终选择了尽量小的运行时实现
- 运行时是那些会被打包到所有程序可执行文件中的 Rust 代码,根据每个语言的设计权衡,运行时虽然有大有小(例如Go语言由于实现了协程和GC ,运行时相对就会大一些),但除了汇编之外,每个语言都拥有它。小运行时的其中一个好处在于最终编译出的可执行文件会相对较小,同时也让该语言更容易被其他语言引入使用
- 而绿色线程/协程的实现会显著增大运行时的大小,因此 Rust 只在标注库中提供了 1:1 的线程模型,如果你愿意牺牲一些性能来换取更精确的线程控制以及更小的线程上下文切换成本,那么可以选择Rust中的 M:N 模型,这些模型由第三方库提供了实现,例如鼎鼎大名的 tokio