首页 > 解决方案 > 在 Common Lisp Bordeaux Threads 中重新启动已退出的线程?

问题描述

有没有办法重新启动已完成任务的线程,以避免为下一个任务创建新线程的开销?(请注意,所有其他处理器/线程都会很忙,并(not (bt:thread-alive-p thread)在线程死亡时发出信号。)例如,我在完成的线程上尝试了 bt:interrupt-thread ,但这不起作用:

* (defparameter *x* 0)
*X*
* (let ((thread (bt:make-thread (lambda () (setf *x* (loop for i from 1 to 10 sum i))))))
    (sleep 1)
    (print *x*)
    (bt:interrupt-thread thread (lambda () (setf *x* (loop for i from 1 to 100 sum i))))
    (sleep 1)
    (print *x*))

55
debugger invoked on a SB-THREAD:INTERRUPT-THREAD-ERROR in thread
#<THREAD "main thread" RUNNING {10012E0613}>:
  Interrupt thread failed: thread #<THREAD "Anonymous thread" FINISHED 
values: 55 {1005D410D3}> has exited.

此外,有没有一种方法可以访问从传递给 bt:make-thread 的函数返回的结果(在线程中),以避免必须通过全局变量进行通信,如上例所示?

标签: multithreadingcommon-lisp

解决方案


当它完成时,它就完成了。通常的技术是让线程运行一个循环,等待某种通道上的一些工作。

lparallelchanl 之类的库可能会有很大帮助。

例如,您可以这样使用chanl

(defun parallel-mayhem (fun count)
  (let* ((start-chan (make-instance 'chanl:channel))
         (results-chan (make-instance 'chanl:channel)))
    (loop :repeat count
          :do (chanl:pexec ()
                (chanl:send start-chan "starting")
                (chanl:send results-chan (funcall fun))))
    (loop :repeat count
          :collect (chanl:recv start-chan))
    (format t "All started.")
    (loop :repeat count
          :collect (chanl:recv results-chan))))

在底层,chanl使用一个简单的线程池。你可以看看它是如何做到的,它非常简洁易读。


推荐阅读