multithreading - 在 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 的函数返回的结果(在线程中),以避免必须通过全局变量进行通信,如上例所示?
解决方案
当它完成时,它就完成了。通常的技术是让线程运行一个循环,等待某种通道上的一些工作。
例如,您可以这样使用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
使用一个简单的线程池。你可以看看它是如何做到的,它非常简洁易读。
推荐阅读
- android - Android 应用程序给出错误 W/BroadcastQueueInjector
- java - Android 流媒体音频延迟随着时间的推移而增加
- c# - 反序列化 Protoc 生成的 C# 类会导致数据被清除
- c++ - OpenGL 使用 glm::rotate 围绕全局轴旋转
- kubernetes - 谷歌云平台 Flink k8s 操作员远程作业 jar 示例无法在 Minikube 上运行
- html - 为什么我的图像在较小的屏幕上从我的 div 中分离出来?
- python - 如何在python中对日期进行排序?
- python - 如何确定要为 Azure Python SDK 类处理哪些异常?
- django - 如何将文件从主机复制到 docker 命名卷
- html - 为什么我的图像向右移动时会调整大小?