系统与数据库2017web.stanford.edu编辑精选
线程对大多数用途而言是个坏主意(1995)
Threads Are a Bad Idea for Most Purposes (1995)
进阶 · 约 25 分钟读完前置知识:操作系统基础、线程与锁、事件驱动/异步编程
导读
这篇 1995 年的文章由 John Ousterhout 撰写,讨论为什么线程对大多数用途而言是坏主意,并主张事件驱动编程通常更简单、更高效。作者并不否认线程在需要真正 CPU 并发时的价值,但认为多数应用并不需要这种并发。核心争议是线程的锁、调试和性能开销与事件模型之间的取舍。
HN 关注点:是因为这是线程与事件驱动编程的经典争论;在如今多核普及的背景下,大家重新评估论文的历史语境、调试成本和现代并发模型。
后来怎么样
这篇论文成为线程与事件驱动编程之争的经典文献,促使后续研究比较并统一两种模型,也影响了异步 I/O、事件循环等服务器编程实践。
HN 评论精选
这几条评论里:质疑 2 补充 1 亲历 1
亲历亲历 1995 年前后线程生态的混乱,认为如今线程工具已成熟,但 futures/promises 等抽象仍难调试。
我开始在 SGI 系统上做大规模并行编程,大约就是这篇论文发表的时候。当时的 SGI 单系统映像最多可有 64 个 CPU,非常新颖。Sun 在做早期多核工作站,Cray 等公司则在推进不同的分布式计算模型。这篇论文出现时,线程用起来非常痛苦。POSIX 线程还很新且大多不受支持,只能用操作系统暴露的东西。在 IRIX 上,你得自己 fork 并建立共享内存池来做线程;在 Solaris 上,有当时最好的早期 pthread 支持;在 Java 里,用原生 Thread 类,而当时它真正只在 Solaris 上能用。一团糟!这个烂摊子现在解决了。Pthreads 无处不在,C++ 有 std::thread,Java 线程到处能用,还有很多新语言漂亮地处理并行,比如 Go 通过 channel 内建的消费者/生产者模型非常优雅。异类是 Win32,但它和 pthreads 足够接近,概念可套用。事件驱动编程也变得线程化了,整个 reactive 框架家族、node.js 等都是这样处理并行。作为一个做这行很久的人,让我困惑的是那些试图隐藏异步操作概念的高层构造,比如 futures、promises。作为概念它们没问题,但很难调试,因为大多数……
oppositelock查看英文原文
I started doing massively parallel programming on SGI systems around the time this paper was published. SGI's at the time could have 64 CPUs in a single system image, which was very novel. Sun was working on its early multi core workstations, and companies like Cray were pushing different models of distributed computation. This paper came at a time when threads were really painful to work with. POSIX threads were still new and mostly unsupported, so you were stuck with whatever your OS exposed. On IRIX, you would do threads yourself by forking and setting up a shared memory pool, on Solaris, you had the best early pthread support, in Java, you used the native Thread classes which only really worked on Solaris at the time. It was a mess! This mess is now solved. Pthreads are everywhere, C++ has std::thread, Java threads work everywhere, and we've had many new language some out which handle parallelism beautifully - for example, the consumer/producer model built into channels in Go is very elegant. The odd one out is Win32, but it's close enough to pthreads for the same concepts to apply. Event driven programming has also become threaded, this is how the whole reactive family of frameworks, node.js, etc, handle parallelism. As someone who's been doing this for a long time, what I find confusing is higher level constructs that try to hide the notion of asynchronous operations, such as futures, promises. As a concept, they're fine, but they're difficult to debug because most developer tools seem not to care about making debugging threads easier.
质疑事件驱动不一定更好调试,tornado 的回调栈和串行化问题明显;宁可用多线程框架。
我不确定事件是否更容易调试。我在工作中大量使用 tornado(基于事件的 Python Web 服务器库)——出问题时你拿不到漂亮的堆栈跟踪,只得到回调面条式代码的随机采样。而且默认情况是一切都在单线程里串行化,每件事都等前驱,哪怕完全无关;不过这可能更多说明该框架而非事件驱动编程本身。老实说,我更愿用真正的多线程框架,虽然我承认它也会以不同方式让开发者日子难过。
yongjik查看英文原文
I'm not exactly sure if events are easier to debug. I use tornado (event-based Python webserver library) extensively at work - when something goes wrong you don't get a nice stack trace, you get some random sampling of callback spaghetti. Also the default state of matters is that everything is serialized in a single thread and everything waits for their predecessor, even when they are totally unrelated, though that probably tells more about the particular framework than event-based programming in general. I'd rather use a real multithread-based framework, honestly, though I concede that it also opens up different ways of making developers' lives miserable.
质疑论文写于多核稀有的年代,作者也承认真 CPU 并发时线程有用;直接套用到今天是错误的。
注意这是 1995 年的文章。当时很多人仍认为多处理器机器是稀罕物,即便在企业里也没什么意思。那份名单里最显眼的是 Linus Torvalds,也包括原文作者 John Ousterhout——他本应更清楚,尤其 Stanford 正是这类东西不那么稀罕的地方之一。他在开头甚至说,当需要真正 CPU 并发时线程仍有用途。如今这是常见情况。把这篇演讲推广到今天,可能比线程本身更糟。
notacoward查看英文原文
Note that it's from 1995. Back then, many people still thought that machines with multiple processors were exotic things of little interest even in the enterprise. That list most notably included one Linus Torvalds. It also included OP author John Osterhout, who should also have known better - even more so, since Stanford was one of the places where such things were not so exotic. He even says, right up front, that threads still have their uses when you need true CPU concurrency. Now that's a common case. Generalizing from this presentation to the current day is probably a worse idea than threads ever were.
补充补充 Morning Paper 关于线程/事件对偶与统一模型的系列文章。
Morning Paper 有一组不错的博客文章讨论这个:为什么它们等价(对偶):https://blog.acolyer.org/2014/12/08/on-the-duality-of-operating-system-structures/ ;为什么线程是坏主意:https://blog.acolyer.org/2014/12/09/why-threads-are-a-bad-idea/ ;为什么事件是坏主意:https://blog.acolyer.org/2014/12/10/why-events-are-a-bad-idea/ ;统一事件和线程(Haskell):https://blog.acolyer.org/2014/12/11/a-language-based-approach-to-unifying-events-and-threads/ ;统一事件和线程(Scala):https://blog.acolyer.org/2014/12/12/scala-actors-unifying-thread-based-and-event-based-programming/
skybrian查看英文原文
The morning paper had a nice set of blog posts about this: Why they're equivalent (duals): https://blog.acolyer.org/2014/12/08/on-the-duality-of-operating-system-structures/ Why threads are a bad idea: https://blog.acolyer.org/2014/12/09/why-threads-are-a-bad-idea/ Why events are a bad idea: https://blog.acolyer.org/2014/12/10/why-events-are-a-bad-idea/ Unifying events and threads (in Haskell): https://blog.acolyer.org/2014/12/11/a-language-based-approach-to-unifying-events-and-threads/ Unifying events and treads (in Scala): https://blog.acolyer.org/2014/12/12/scala-actors-unifying-thread-based-and-event-based-programming/
相关资源
从这篇论文所有 HN 讨论帖的全部评论里整理出来的链接。
- 视频与演讲
历次讨论
- 2017Hacker News 讨论帖175 分 · 148 评
- 2020Hacker News 讨论帖248 分 · 234 评
同领域还值得读
I/O 比 CPU 更快——让我们划分资源并消除操作系统抽象
I/O Is Faster Than CPU – Let’s Partition Resources and Eliminate OS Abstractions
指出在现代服务器硬件上 I/O 速度已接近甚至超过 CPU,传统操作系统抽象反而成为瓶颈。
系统与数据库2019 · 817 分 · 277 评进阶 · 约 30 分钟编辑精选使用 io_uring 的高效 I/O
Efficient IO with io_uring
由 Linux 内核开发者 Jens Axboe 撰写,介绍 Linux 新的异步 I/O 接口 io_uring。
系统与数据库2019 · 426 分 · 96 评进阶 · 约 45 分钟编辑精选学习型索引结构之论证
The Case for Learned Index Structures
提出把索引看作一种"模型":既然 B-tree 等结构本质上是在学习数据的分布,就可以用机器学习模型(如回归模型、神经网络)来近似键到位置的映射,从而替代 B-tree、哈希索引…
系统与数据库2017 · 398 分 · 66 评 · 引用 25进阶 · 约 60 分钟编辑精选FoundationDB:一个分布式、解耦的事务型键值存储
FoundationDB: A distributed, unbundled, transactional key value store
介绍 FoundationDB:一个分布式、解耦设计的事务性键值存储。
系统与数据库2021 · 283 分 · 99 评进阶 · 约 90 分钟编辑精选SQLite:过去、现在与未来
SQLite: Past, Present, and Future
这篇 VLDB 论文梳理 SQLite 的历史、当前架构与性能表现,并展望未来方向。
系统与数据库2022 · 282 分 · 86 评进阶 · 约 40 分钟编辑精选