如何保护主线程不受子线程(SBCL)引起的错误的影响



我目前正在使用SBCL提供的sb-thread API,想知道如果在启动的线程中抛出错误会发生什么,以及如何确保只有该进程受到影响(并死亡),而没有其他进程受到影响,因为显然即使主线程没有抛出错误,也会进入调试器。

* (handler-case 
    (sb-thread:join-thread (sb-thread:make-thread #'(lambda()
                              (error 'simple-error))))
  (sb-thread:join-thread-error (err)
    (sb-thread:thread-error-thread err)
    (FORMAT t "allemeineentchen~%")))
(A SIMPLE-ERROR was caught when trying to print *DEBUG-CONDITION* when entering
the debugger. Printing was aborted and the SIMPLE-ERROR was stored in
SB-DEBUG::*NESTED-DEBUG-CONDITION*.)
;after this sbcl just yields until str-c enters the debugger

我的建议是让每个线程的函数体以(handler-case (body) (error (err) err)开头,但这似乎是非常不标准/错误的,只适用于函数体由我创建的线程,我不确定这是否会在任何情况下阻止进入调试器。

有没有关于这个主题的指导方针/(非官方)标准?

您需要非常清楚正在发出信号的内容和正在处理的内容(以及在哪里):首先,您试图处理什么错误情况?当你用"简单错误"调用#"线程中的错误"时,这是一个问题,因为sbcl将无法打印你发出的错误信号,但除此之外,一切都正常工作。如果我这样做:

(handler-case 
         (sb-thread:join-thread 
          (sb-thread:make-thread #'(lambda()
                                     (error "simple error"))))
       (simple-error (c)
         c)
       (sb-thread:join-thread-error (c)
         (sb-thread:thread-error-thread c)))

Sbcl正确地为未处理的简单错误进入调试器,但是在我使用调试器的中止重新启动后发出信号的连接线程错误确实得到了处理,我想这就是你所问的:

simple error
[Condition of type SIMPLE-ERROR]
Restarts:
 0: [ABORT] Abort thread (#<THREAD RUNNING {DABCAD1}>) 0 ==> #<SB-THREAD:THREAD ABORTED {DABCAD1}>

编辑:我在阅读了Sim的评论后添加了这个:

如果你只想忽略线程中的任何错误,那么就这样做:

(sb-thread:join-thread 
          (sb-thread:make-thread #'(lambda() (ignore-errors
                                               (error "simple error")))))

最新更新