Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
34 lines (30 sloc) 1.54 KB

Louis 觉得书中正文给出make-account-and-serializer过于麻烦,给出了自己的改进版

(define (make-account-and-serializer balance)
  (define (withdraw amount)
    (if (>= balance amount)
      (begin
        (set! balance (- balance amount))
        balance)
      "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (let ((balance-serializer (make-serializer)))
    (define (dispatch m)
      (cond
        ((eq? m 'withdraw) (balance-serializer withdraw))
        ((eq? m 'deposit) (balance-serializer deposit))
        ((eq? m 'balance) balance)
        ((eq? m 'serializer) balance-serializer)
        (else (error "Unknown request -- MAKE_ACCOUNT" m))))
    dispatch))

主要在返回withdrawdeposit时,用balance-serializer处理过后再返回,然后取款时和最早的方式一样,如下

(define (deposit account amount)
  ((account 'deposit) amount))

如果采用了 Louis 的方式,这里有个大坑,那就是会死锁

Deadlock

因为我们在调用serialized-exchange过程时,已经拿到了account1account2serializer,如果这时再去执行account1account2withdrawdeposit过程时,会发现需要等待另一个账户的serializer的释放,而这个serializer的释放,依赖于它们本身的完成,这就造成了死锁。