naga:3-38 > 3-49

Todo

3.46
3.48
3.49

Exercise 3.38

;;a: 6通り
;;  Peter-Paul-Mary:45
;;  Peter-Mary-Paul:35
;;  Paul-Peter-Mary:45
;;  Paul-Mary-Peter:50
;;  Mary-Peter-Paul:40
;;  Mary-Paul-Peter:40
;;b: 210通り
;; $25
;;  Peter: (+ 100 10) (set! balance 110) 
;;  Paul :  (- 100 20)                   (set! balance 80)
;;  Mary                                (/ 110 2)         (- 80 55) (set! balance 25)
;; $110
;;  Peter: (+100 10)                                              (set! balance 110)
;;  Paul :  (- 100 20) (set! balance 80)
;;  Mary :                              (/ 80 2) (- 80 40) (set! balance 0)

Exercise 3.39

;;100, 101, 121 が残る

Exercise 3.40

;;serialized procedures でない場合
;;(1000000 100 10000 1000) のどれか。
;;serialized procedures の場合
;;1000000

Exercise 3.41

;;1度の参照では、serialize は不要。

Exercise 3.42

;; 安全のように思える???

Exercise 3.43

;; exchange は各account の balance を入れ替える処理なので、最初の各account の
;; 値が$10,$20,$30であれば、何度 exchange を実行しても、各accountの balance
;; は$10,$20,$30の組合せとなる。

;;(define (exchange account1 account2)          ;;
;;  (let (defference (- (account1 'balance)
;;                      (account2 'balance)))   ;; a
;;    ((account1 'withdraw) difference)         ;; b
;;    ((account2 'deposit) difference)))        ;; c
;;
;;           a1            a2             a3
;;初期値
;;       balance:10    balance:20     balance:30
;;a         difference=20-10
;; a                        difference=30-20
;; b                                  balance:20
;; c                   balance:30
;;b                    balance:20
;;c      balance:20
;;この version の exchange は withdraw と deposit の処理は serialize されている
;;ので、求めたdifferenceが正しいとは限らないが、その値を移す処理自体は正しい。
;;従って、合計が最初と変わることはない。

;;withdraw、deposit が serialize されていなければ Fig3.29 にあるように合計も
;;変わってしまう。

Exercise 3.44

;; 正しくない。
;; exchange は口座の金額を入れ替えることが目的であり、そのために差額を
;; 算出する。この算出過程が serialize されていないと正しい差額が算出で
;; きない。
;; 一方 transfer は移す金額はきまっており、その移動にための処理である。
;; withdraw, deposit は serialize されているので Ben の方法で問題ない。

Exercise 3.45

;; serialized-exchange が呼び出されると exchange がそれぞれの口座の
;; serializer で serialize された状態で呼び出される。 exchage の中で
;; withdraw を呼び出すが、これもその口座の serializer で serialize
;; しようとするので、その時点でデッドロックが発生する。

Exercise 3.46

;; test-and-set! を atomic でなく実装すると、複数のプロセスが
;; test-and-set! の (car cell) を同時に #f と評価してしまい、
;; (mutex 'acquire) が正しく機能しない。

;; 図は後日

Exercise 3.47

;; a
;; acquire していないプロセスが release しても ok
(define (make-semaphore n)
  (let ((mutex (make-mutex))
        (sval n))
    (define (the-semaphore m)
      (mutex 'acquire)
      (cond ((eq? m 'acquire)
             (cond ((> sval 0)
                    (set! sval (- sval 1)))
                   (else (mutex 'release) (the-semaphore m))))
            ((eq? m 'release)
             (set! sval (+ sval 1))))
      (mutex 'release)sval)
    the-semaphore))

;; b
(define (make-semaphore n)
  (let ((cell (list #f))
        (sval n))
    (define (the-semaphore m)
      (if (test-and-set! cell)
          (the-semaphore m)
          (cond ((eq? m 'acquire)
                 (cond ((> sval 0)
                        (set! sval (- sval 1)))
                       (else (clear! cell) (the-semaphore m))))
                ((eq? m 'release)
                 (set! sval (+ sval 1)))))
      (clear! cell))
    the-semaphore))
a.とb.の内容に差が無い。問題の読み方間違えているかも。

Exercise 3.48

Exercise 3.49

タグ:

+ タグ編集
  • タグ:
最終更新:2008年07月26日 14:22
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。