13. 应对 (并发) Bugs

背景回顾:我们已经了解常见的并发 bug 类型:死锁、数据竞争、原子性/顺序违反。与此同时,在编程时消灭并发 bug 仍然是一个世界性的难题。那么,我们应该如何应对这些并发 bugs?

本讲内容另一节真正的实用 “编程” 课:如何正确地 (并发) 编程:应对三种常见的 “死亡” 方式:死锁 (deadlock)、死局 (软件危机中的 dead end)、死线 (deadline)。

13.2 应对死锁

13.3 应对死局:绝处逢生

没错,在 “有 specification” 的情况下,开发者一定会想到合适的方法检查它们,以提高软件的质量。很显然,C 语言只提供 “底层机制” 的设计,在管理大型复杂项目时捉襟见肘。Linux Kernel 如果没有 ASAN 和 TSAN 机制,将会变得千疮百孔。

13.4 应对死线 (Deadline):防御性编程

Takeaway Messages

Bugs (包括并发 bugs) 一直以来困扰着所有软件工程的实践者。我们不仅要应对 specification crisis (定义到底什么是对的),甚至即便知道 specification,也难以应对现代软件的复杂性。为了部分应对这一点从而实现 “更正确” 的软件,我们把对程序的预期表达在程序中 (race-free, lock ordering, ...),而不是让程序在自然状态下悄悄进入有问题的状态,就是我们目前解决程序调试问题的折中办法。“山寨” sanitizer 给我们带来的启发则是:如果我们能清楚地追溯到问题产生的本源,我们就总是能找到好的应对方法——山寨的 sanitizers 在暗中帮助你实现 fail-fast 的程序,从而减轻你调试问题的负担。希望这节课能启发、帮助你重新思考 “编程” 这件事。

课后习题/编程作业

📚阅读材料

教科书 Operating Systems: Three Easy Pieces

  • 第 32 章 - Concurrency Bugs