Clojure的“send”和“send-off”函数在将操作分派给代理时有什么区别?

27
Clojure API将这两个函数描述为:
(send a f&args)-将操作分派给代理。立即返回代理。随后,代理的状态将在线程池中的线程中设置为:(apply action-fn state-of-agent args)
(send-off a f&args)-将可能会阻塞的操作分派给代理。立即返回代理。随后,在单独的线程中,代理的状态将被设置为:(apply action-fn state-of-agent args)
唯一明显的区别是在进行可能会阻塞的操作时应该使用send-off。请问有人能更详细地解释这两个函数的差异吗?
1个回答

28

使用send将发送给任何代理的所有操作都在线程池中运行,并比实际处理器数量多几个线程。 这使它们更接近于CPU的全负载运行。 如果您使用send进行1000次调用,则不会产生太多的切换开销,无法立即处理的调用只需等待处理器可用。 如果它们被阻塞,则线程池可能会用尽。

当您使用send-off时,每个调用都会创建一个新线程。 如果您使用send-off进行1000个函数调用,则无法立即处理的函数仍然等待下一个可用处理器,但是如果send-off线程池运行不足,它们可能会产生启动线程的额外开销。 如果线程被阻塞也没关系,因为每个任务(潜在地)都会获得一个专用线程。


15
送行并不会创建一个新的线程,它使用一个不同的、可扩展的线程池。 - pmf
1
谢谢:我会编辑以包含那个。感谢指出。 - Arthur Ulfeldt
1
我认为,如果您有足够的额外资源,并且正在进行像IO这样有很多阻塞的操作,那么发送异步任务的变体会很好;而如果您正在进行CPU密集型操作,则直接发送变体将更有效率。 - gleenn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接