假设这个简单的循环在一个子线程中,每秒执行step
,而你可以通过REPL与之交互(检查state
或更改step
):
(import (srfi 18) (chicken repl))
(define mutex (make-mutex))
(define (with-mutex-locked mutex thunk) (dynamic-wind
(lambda () (mutex-lock! mutex))
(lambda () (thunk))
(lambda () (mutex-unlock! mutex))))
(set! state 0)
(define (step) (set! state (+ state 1)))
(define (loop)
(with-mutex-locked mutex step)
(sleep 1)
(loop))
(thread-start! loop)
(repl (lambda (x) (with-mutex-locked mutex (lambda () (eval x)))))
(exit)
但是,当将step
更改为错误时,线程崩溃并打印跟踪:
(define (step) (car `()))
Warning (#<thread: thread26>): in thread: (car) bad argument type: ()
Call history:
<eval> [loop] (loop)
<eval> [loop] (dynamic-wind (lambda () (mutex-lock! mutex)) (lambda () (step)) (lambda () (mutex-unlock! mutex)))
<eval> [loop] (mutex-lock! mutex)
<eval> [loop] (step)
<eval> [step] (car (quasiquote ())) <--
我想从这样的崩溃中恢复(即解锁互斥锁,重新启动循环),但仍然有错误,其跟踪打印用于调试。我对(handle-exceptions … (step))
的尝试没有成功,因为异常显然只包含message
,arguments
和location
-而不是跟踪。但是跟踪必须隐藏在某个地方,否则解释器无法打印它。有办法进入吗?或者在追踪被打印出来之后还有其他恢复的方法吗?
跟踪缓冲区是一个只包含最近调用的环缓冲区。它不能用来跳回去。
你可能想要阅读这期CHICKEN Gazette的老问题,其中包含一个教程(搜索"煎蛋卷食谱"),关于异常处理是如何工作的,以及可持续异常和不可持续异常之间的区别。如果你赶时间,真正的解释从"继续还是不继续——这是问题所在"开始。