/* Page prose (zh-Hans) */
"Reentrancy" = "# 重入：微妙之处\n\n这里就是 actor 让人意外的地方。actor 保证一次只有一个任务在里面，但“一次”有一个精确的含义。每当一个 actor 方法碰到 `await` 并**挂起**时，它在等待期间会*走出 actor*。现在 actor 空闲了，于是**另一个任务可以进入**。这称为**重入**：actor 可以在一次挂起期间被重新进入。\n\n后果很尖锐：**你在 `await` 之前读到的任何值，到你恢复时都可能已经变了。** 状态不会在一次挂起期间保持冻结。\n\n看它引发一个真正的 bug。这个金库会检查余额，在交易中途做一个异步步骤（想象一下联系一个审批服务），然后扣款。";
"Reentrancy-2" = "**观察运行：**两个柜员都报告成功，而最终余额是 **`-60`**：账户被透支了，尽管每一次取款都仔细检查过有足够的钱。下面是这个顺序：\n\n1. 柜员 A 进入，检查 `100 >= 80`（通过），然后碰到 `await` 并**挂起**，释放了 actor。\n2. 由于 actor 空闲，柜员 B 进入，检查 `100 >= 80`（也通过；A 还没扣款！），然后同样碰到 `await` 并挂起。\n3. 两个都醒来并扣款：`100 - 80 = 20`，然后 `20 - 80 = -60`。\n\n对两者来说 guard 都为真，因为余额*在任何一方挂起期间*都没有变，但它*在检查与扣款之间*变了。那个间隙就是 `await`。这个先检查再行动终究不是原子的。\n\n* callout(试一试): 把 sleep 改成 `.seconds(2)`；透支照样发生。等更久不是解法；合上跨越 `await` 的那个间隙才是。\n\n[上一页](@previous)  |  第 4 / 7 页  |  [下一页: 防范重入](@next)";
