make-serializer で生成されるオブジェクトは,関数を引数に取って,直列化された関数を返すシリアライザ.直列化された関数は,その実行時にインタリーブされない.そのために,
(define x 10) (define s (make-serializer)) (parallel-execute (s (lambda () (set! x (* x x)))) (s (lambda () (set! x (+ x 1)))))
上の一連の関数を実行すると,最終的な x の値は
(lambda () (set! x (* x x)))
が先に実行された場合の 101 か,
(s (lambda () (set! x (+ x 1))))
が先に実行された場合の 121 のどちらかに制限される.
じゃぁ,下記を実行した後の最終的な x の値はどうなり得るのか.
(define x 10) (define s (make-serializer)) (parallel-execute (lambda () (set! x ((s (lambda () (* x x)))))) (s (lambda () (set! x (+ x 1)))))
まず,101 と 121 は最終的な x の値としてあり得るのは自明.今回は
(lambda () (set! x ((s (lambda () (* x x))))))
上記関数において, の計算と x への代入との間にインタリーブされる可能性がある.実際にそのとき何が起こるのかを考えることにする.parallel-execute の第一引数に渡されている関数を p1,第二引数となっている関数を p2 とすると,
- x が 100 (初期状態)
- p1 が を計算する
- p2 が x に 11 を代入する (インタリーブ)
- p1 が x に 100 を代入する.
というわけで,x が 100 になる可能性がある.
以上から,x が取る値としては,100,121,101 がある.