灯下 登录
计算机科学 / SICP / 3.4.2 Mechanisms for Controlling Concurrency

Exercise 3.41 · 习题

Exercise 3.41: Ben Bitdiddle worries that it
would be better to implement the bank account as follows (where the commented
line has been changed):

(define (make-account balance)
(define (withdraw amount)
(if (>= balance amount)
(begin
(set! balance
(- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(let ((protected (make-serializer)))
(define (dispatch m)
(cond ((eq? m 'withdraw)
(protected withdraw))
((eq? m 'deposit)
(protected deposit))
((eq? m 'balance)
((protected
(lambda ()
balance)))) ; serialized
(else
(error
"Unknown request:
MAKE-ACCOUNT"
m))))
dispatch))

because allowing unserialized access to the bank balance can result in

anomalous behavior. Do you agree? Is there any scenario that demonstrates

Ben’s concern?

练习 3.41:Ben Bitdiddle 担心,最好按如下方式实现银行账户(其中注释行已作修改):

(define (make-account balance)
(define (withdraw amount)
(if (>= balance amount)
(begin
(set! balance
(- balance amount))
balance)
“Insufficient funds”))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(let ((protected (make-serializer)))
(define (dispatch m)
(cond ((eq? m 'withdraw)
(protected withdraw))
((eq? m 'deposit)
(protected deposit))
((eq? m 'balance)
((protected
(lambda ()
balance)))) ; serialized
(else
(error
“Unknown request:\nMAKE-ACCOUNT”
m))))
dispatch))

因为允许对银行余额进行非串行化访问可能导致异常行为。你同意吗?是否存在某种情景能证明 Ben 的担忧?

Racket #lang sicp
(define (make-account balance)
 (define (withdraw amount)
 (if (>= balance amount)
 (begin
 (set! balance
 (- balance amount))
 balance)
 "Insufficient funds"))
 (define (deposit amount)
 (set! balance (+ balance amount))
 balance)
 (let ((protected (make-serializer)))
 (define (dispatch m)
 (cond ((eq? m 'withdraw)
 (protected withdraw))
 ((eq? m 'deposit)
 (protected deposit))
 ((eq? m 'balance)
 ((protected
 (lambda ()
 balance)))) ; serialized
 (else
 (error
 "Unknown request:
 MAKE-ACCOUNT"
 m))))
 dispatch))