cl-cookbook icon indicating copy to clipboard operation
cl-cookbook copied to clipboard

Elaborate on why BT:DESTROY-THREAD is a bad idea

Open phoe opened this issue 4 years ago • 0 comments

Augment https://lispcookbook.github.io/cl-cookbook/process.html#joining-on-a-thread-destroying-a-thread with the following:

Using bt:destroy-thread is a bad idea in the general case. Threads should instead finish on their own to do all the cleanup that they might need to do - one should never use bt:destroy-thread in production code. Destroying threads from outside is only feasible as a measure of last resort, as it can and eventually will leave the application in an unknown state.

It is better to bt:interrupt-thread #'break and select the bottommost abort restart in order to let the thread unwind completely. A programmatic version of this would be:

(defun abort-thread (thread)
  (flet ((thunk ()
           ;; We must call COMPUTE-RESTARTS in the dynamic context of the thread
           ;; that we want to abort, not of the thread that performs the
           ;; interruption.
           (let* ((restarts (compute-restarts))
                  ;; We assume that the last ABORT restart causes the whole
                  ;; thread to unwind and exit gracefully.
                  (abort-restarts (remove-if-not (alexandria:curry #'eq 'abort)
                                                 restarts :key #'restart-name))
                  (abort-thread-restart (alexandria:lastcar abort-restarts)))
             (invoke-restart abort-thread-restart))))
    ;; Interrupt the target thread with our thunk and force it to invoke the
    ;; ABORT restart, therefore initiating the unwind.
    (bt:interrupt-thread thread thunk)))

TODO: check if this works on implementations other than SBCL.

phoe avatar Jun 18 '21 11:06 phoe