3.4 Concurrency: Time Is of the Essence

久々に読む。なんか読みにくくて和訳版の本読んでみたけど同じくらいわかりにくかった…。
この節は多くの問題を省略。図を描いたりただ調べるだけのが多いので。

3.41

一つの処理しか行わない手続きを直列化することに意味はない。

3.42

よく分からない。問題ない気がするけど問題あるんだろうなぁ。

3.44

withdraw,depositだけからなる手続きは直列化する必要はない。途中で預金の量が変わっても何も問題はないから。

3.45

必要以上にserializeしてしまうってことしか思い付かない。

3.47 (セマフォの実装)

mutex版
(define (make-semaphore size)
  (let ((count 0)
        (mutex (make-mutex)))
    (lambda (proc)
      (define (serialized-proc . args)
        (set! count (+ count 1))
        (if (> count size)
          (begin
            (mutex 'acquire)
            (let ((result (apply proc args)))
              (mutex 'release)
              result))
          (apply proc args))
        (set! count (- count 1))
        )
      serialized-proc
      )))
test-and-set!版
(define (make-semaphore size)
  (let ((count 0)
        (cell (list #f)))
    (define (the-semaphore m)
      (cond ((eq? m 'acquire)
             (cond ((> size count)
                    (set! count (+ count 1)))
                   ((test-and-set! cell)
                    (the-semaphore 'acquire))
                   (else
                    (set! count (+ count 1)))))
            ((eq? m 'release)
             (set! count (- count 1))
             (clear! cell))))
    the-semaphore))

あやしい。テストできないからなおさら。アルコール入ってるからなおさら。

3.48

(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) balance)
            (else (error "Unknown request -- MAKE-ACCOUNT"
                         m))))
    dispatch))

3.49 (口座idによるデッドロック回避機構が効かないような場合)

いったんwithdrawして、その結果によってdeposit先を選択するような場合かな…?