|
| 1 | +#+LATEX_CLASS: ramsay-org-article |
| 2 | +#+LATEX_CLASS_OPTIONS: [oneside,A4paper,12pt] |
| 3 | +#+AUTHOR: Ramsay Leung |
| 4 | + |
| 5 | +#+DATE: 2025-07-22 Tue 19:56 |
| 6 | +* 序列化执行,并发交换 |
| 7 | + 如果这些进程是顺序进行的(run sequentially),那么经过任何次并发交换,这意味着: |
| 8 | + |
| 9 | + 每个交换操作是原子的(完整执行),那么每次交换只是重新排列三个账户的余额,结果必然是三个原始值($10,$20,$30)的某种排列。 |
| 10 | +* 非序列化交换 |
| 11 | + #+begin_src plantuml :file ../img/chapter3/exercise3-43-1.png :exports results |
| 12 | + @startuml |
| 13 | + title 非序列化交换 |
| 14 | + participant "Process 1\n(Exchange A-B)" as P1 |
| 15 | + participant "Account A" as A |
| 16 | + participant "Account B" as B |
| 17 | + participant "Account C" as C |
| 18 | + participant "Process 2\n(Exchange A-C)" as P2 |
| 19 | + |
| 20 | + note over A, C: Initial State: A=10, B=20, C=30 |
| 21 | + |
| 22 | + P1 -> A: Read balance |
| 23 | + A --> P1: 10 |
| 24 | + note right: P1 reads A: 10 |
| 25 | + |
| 26 | + P1 -> B: Read balance |
| 27 | + B --> P1: 20 |
| 28 | + note right: P1 reads B: 20\nP1 diff: 10-20 = -10 |
| 29 | + |
| 30 | + P2 -> A: Read balance |
| 31 | + A --> P2: 10 |
| 32 | + note left: P2 reads A: 10 |
| 33 | + |
| 34 | + P2 -> C: Read balance |
| 35 | + C --> P2: 30 |
| 36 | + note left: P2 reads C: 30\nP2 diff: 10-30 = -20 |
| 37 | + |
| 38 | + P1 -> A: Withdraw -10 (= Deposit 10) |
| 39 | + A --> P1: Success |
| 40 | + note over A: A = 10 + 10 = 20 |
| 41 | + |
| 42 | + P2 -> A: Withdraw -20 (= Deposit 20) |
| 43 | + A --> P2: Success |
| 44 | + note over A: A = 20 + 20 = 40 |
| 45 | + |
| 46 | + P1 -> B: Deposit -10 (= Withdraw 10) |
| 47 | + B --> P1: Success |
| 48 | + note over B: B = 20 - 10 = 10 |
| 49 | + |
| 50 | + P2 -> C: Deposit -20 (= Withdraw 20) |
| 51 | + C --> P2: Success |
| 52 | + note over C: C = 30 - 20 = 10 |
| 53 | + |
| 54 | + note over A, C: Final State: A=40, B=10, C=10\n(理应是 {10, 20, 30}的某种组合) |
| 55 | + note over A, C: 总和是: 40 + 10 + 10 = 60 |
| 56 | + note over A, C: 单个账户余额异常 |
| 57 | + |
| 58 | + @enduml |
| 59 | + #+end_src |
| 60 | + |
| 61 | + #+RESULTS: |
| 62 | + [[file:../img/chapter3/exercise3-43-1.png]] |
| 63 | +* 不做各个账户交易的串行化 |
| 64 | + #+begin_src plantuml :file ../img/chapter3/exercise3-43-2.png :exports results |
| 65 | + @startuml |
| 66 | + title SICP Exercise 3.43: not serialize the transactions on individual accounts |
| 67 | + participant "Process 1" as P1 |
| 68 | + participant "Account A" as A |
| 69 | + participant "Process 2" as P2 |
| 70 | + |
| 71 | + note over A: Initial: Account A = 10 |
| 72 | + |
| 73 | + P1 -> A: Read current balance |
| 74 | + A --> P1: 10 |
| 75 | + |
| 76 | + P2 -> A: Read current balance |
| 77 | + A --> P2: 10 |
| 78 | + |
| 79 | + P1 -> P1: 10 - 5 = -5 |
| 80 | + |
| 81 | + P2 -> P2: 10 + 10 = 20 |
| 82 | + |
| 83 | + P1 -> A: Write new balance = -5 |
| 84 | + |
| 85 | + P2 -> A: Write new balance = 20\n(P1的更新丢失了) |
| 86 | + |
| 87 | + note over A: Final: Account A = 20 |
| 88 | + note over P1, P2: Expected: 10 - 5 + 10 = 15 |
| 89 | + note over P1, P2: Actual: 20 |
| 90 | + @enduml |
| 91 | + #+end_src |
| 92 | + |
| 93 | + #+RESULTS: |
| 94 | + [[file:../img/chapter3/exercise3-43-2.png]] |
0 commit comments