; ex-3.38 ; Peter: (set! balance (+ balance 10)) ; Paul: (set! balance (- balance 20)) ; Mary: (set! balance (- balance (/ balance 2))) ; ; a. ; Peter->Paul->Mary, 110->90->45 ; Peter->Mary->Paul, 110->55->35 ; Paul->Peter->Mary, 80->90->45 ; Paul->Mary->Peter, 80->40->50 ; Mary->Peter->Paul, 50->30->40 ; Mary->Paul->Peter, 50->60->40 ; ; b. ; Peter->$100にアクセス->新しい値100-10=90->残高を90ドルに設定 ; ; Paul --->$100にアクセス->新しい値100-20=80->残高を80ドルに設定 ; ; 銀行:$100->$90->$50->$80 ; ; Mary -->$100にアクセス->新しい値100-50=50->残高を50ドルに設定 ; ; それぞれのbalanceが別で定義されているので、最初に全員が$100にアクセスしてそれを元に計算するからおかしくなる。 ; アクセスのタイミングと新しい値の設定のタイミングによってはもっと複雑になり得る。 ; ex-3.39 ; 101, 121, 100 ; ex-3.40 ; 最初のlambdaをP1, 次をP2と呼称する. ; ; 混じらない場合 ; P1: 10 * 10 = 100, P2: 100 * 100 * 100 = 1000000 ; P1: 10 * 10 * 10 = 1000, P2: 1000 * 1000 = 1000000 ; ; P1が無視された場合 ; P2: 10 * 10 * 10 = 1000 ; ; P1が混じった場合 ; P2: 10 * 100 * 100 = 100000 ; P2: 10 * 10 * 100 = 10000 ; ; P2が無視された場合 ; P1: 100 * 100 = 10000 ; P1: 10 * 100 = 1000 ; P1: 10 * 10 = 100 ; ; 残るのは以下の2つだけ ; P1: 10 * 10 = 100, P2: 100 * 100 * 100 = 1000000 ; P1: 10 * 10 * 10 = 1000, P2: 1000 * 1000 = 1000000 ; ex-3.41 ; withdrawやdepositなどの書き換えではなくbalanceを返しているだけなので不要. ; ex-3.42 ;安全な変更, 並列性に違いはない. ; ex-3.43 ; 残高の合計の保存が破れる場合 ; Paul が withdraw、 deposit 実行時に、 a の値を調べるプロセスと a に新値を Set するプロセスとの間に Peter が a の値を新値に Set してしまう。 ; ex-3.44 ; 交換(exchange)の場合とは違い残高の差(difference)を計算する必要がなく、transfer 実行時に指定するために Ben Bitdiddle の主張の方が正しい。 ; ex-3.45 ; withdraw、deposit 手続きの部分で serializer が入れ子になるので処理が終わらない。 ; ex-3.46 ; cell が true の間は他のプロセスは 相互排除器(mutex)を使えない。 ; 2つのプロセスが同時に相互排除器を獲得するとプロセスの相互排除機能が破綻する。