考慮以下程式
let xxx () =
match k () with
| effect A, k ->
Thread.create (fun () -> continue k ()) ();
continue k ()
假設是使用紀錄 sp
的方式實作,現在 thread 會在未知的時間點把 sp
設定成 k
,而 xxx
會立即設定成 k
並繼續執行。
換句話說 thread 跟 xxx
會以未知的順序讓兩個計算實體對 k
的記憶體進行修改,這就是我想問的問題。
應對一:複製整個 k
的記憶體內容
我跟朋友討論之後他提出一種方法:另一個 thread 要捕獲 k
必須複製整個 k
的記憶體內容,這種方法就可以避免在資料損壞的 stack 上繼續運作。
這個方法很實務,對理論沒有修改。所有這類複製都有很大的執行代價。
應對二:runtime 禁止
下面這個 chez scheme 的程式是會卡住的。
(import (chezscheme))
(define handler-key (gensym))
(define th #f)
(define x 0)
(define (sub)
(define n
(call/cc (lambda (k)
(define abort (continuation-marks-first (current-continuation-marks) handler-key))
(abort k))))
(set! x (+ x n)))
(write x)
(newline)
(with-continuation-mark
handler-key (lambda (resume)
(set! th (fork-thread (lambda () (resume 20))))
(resume 10))
(sub))
(write x)
(newline)
(thread-join th)
這個方法的缺點是損壞的方式很不穩定。