练习 3.41

Ben 的担心是没有必要的,取余额的操作并不对 balance 变量进行设置,它是一个原子性的只读操作。即使在访问 balance 变量时有其他设置操作在进行,解释器也会很好地处理这一状况,所以就算不对 balance 进行串行化,也可以正确地获取 balance 的值。

为了验证以上的推论,假设现在有余额为 100 的银行帐号,对于 withdrawdepositbalance 三种操作,可能出现的并行情况有两种(因为 withdrawdeposit 已经进行了串行化,所以这两个操作的并行情况不可能出现):

  1. 一个进程执行 ((protected withdraw) 50) 操作,另一个进程并行访问 balance 变量
  2. 一个进程执行 ((protected deposit) 35) 操作,另一个进程并行访问 balance 变量

这两种并行共有四种可能的运行序列(每个并行两种):

序列一: withdraw –> balance

序列二: balance –> withdraw

序列三: deposit –> balance

序列四: balance –> deposit

对于运行序列一, withdraw 将银行帐号的余额设置为 50 ,然后 balance 返回 50

对于运行序列二 , balance 返回帐号 100 ,然后 withdraw 将银行帐号设置为 50

对于运行序列三 , deposit 将银行帐号的余额设置为 135 ,然后 balance 返回 135

对于运行序列四 , balance 返回余额 100 ,然后 deposit

可以看到,在以上四种运行序列中,对 balance 的访问都不会造成任何的并发错误,而 balance 操作也可以正确地返回帐号当时的余额。

讨论

blog comments powered by Disqus