背景回顾:我们已经了解常见的并发 bug 类型:死锁、数据竞争、原子性/顺序违反。与此同时,在编程时消灭并发 bug 仍然是一个世界性的难题。那么,我们应该如何应对这些并发 bugs?
本讲内容:另一节真正的实用 “编程” 课:如何正确地 (并发) 编程:应对三种常见的 “死亡” 方式:死锁 (deadlock)、死局 (软件危机中的 dead end)、死线 (deadline)。
没错,在 “有 specification” 的情况下,开发者一定会想到合适的方法检查它们,以提高软件的质量。很显然,C 语言只提供 “底层机制” 的设计,在管理大型复杂项目时捉襟见肘。Linux Kernel 如果没有 ASAN 和 TSAN 机制,将会变得千疮百孔。
Bugs (包括并发 bugs) 一直以来困扰着所有软件工程的实践者。我们不仅要应对 specification crisis (定义到底什么是对的),甚至即便知道 specification,也难以应对现代软件的复杂性。为了部分应对这一点从而实现 “更正确” 的软件,我们把对程序的预期表达在程序中 (race-free, lock ordering, ...),而不是让程序在自然状态下悄悄进入有问题的状态,就是我们目前解决程序调试问题的折中办法。“山寨” sanitizer 给我们带来的启发则是:如果我们能清楚地追溯到问题产生的本源,我们就总是能找到好的应对方法——山寨的 sanitizers 在暗中帮助你实现 fail-fast 的程序,从而减轻你调试问题的负担。希望这节课能启发、帮助你重新思考 “编程” 这件事。