先回顾一个并发 Bug

在捡起东西的瞬间 “拿起” 物品,“拿起” 的物品会变成 “捡起” 的物品

  • 视频
  • 似乎是由共享状态引起的

v = "$1";
// Expected timing
// InHand = v;

Event(pickup) {
    v = "$99";
    Inventory.append(v);
}

// Actual timing
InHand = v;

“Killed by a Machine”

Therac-25 Incident (1985-1987)

  • 至少导致 6 人死亡
  • 事件驱动导致的并发 bug (没有多线程)

The Therac-25

在更早的产品中,使用电路互锁 (interlock) 在 assert fail 时停机

assert mode in [XRay, Electron]
assert mirror in [On, Off]
assert not (mode == XRay and mirror == Off)

The Killer Software Bug in History

原子性 + 异步执行假设导致的灾难

  • 选择 X-ray Mode
    • 机器开始移动 mirror
    • 需要 ~8s 完成
  • 此时切换到 Electron Mode
    • 射线源以 X-ray Mode 运行
    • Mirror 尚未到位
    • Malfunction 54
      • 每天处理各种 Malfunction 的操作员下意识地 Continue
      • 灾难发生

这甚至不是 Therac-25 里的最后一个杀人 Bug

问题修复后……

  • If the operator sent a command at the exact moment the counter overflowed, the machine would skip setting up some of the beam accessories

最终解决方法

  • 独立的硬件安全方案
  • 在大计量照射发生时直接停机