当我编写更多core.async代码时,出现的一个非常常见的模式是一个循环,它会在一系列通道上发生变化,并且会响应一条消息而起作用,例如:
(go-loop [state {}]
(let [[value task] (alts! tasks)]
...work...
(recur state))
我不觉得我理解实际工作的各种方式的权衡,所以我想我会尝试在这里探索它们。
此摘要是否正确且全面?
答案 0 :(得分:5)
如果要完成的工作完全受CPU限制,那么我可能会在go
块中内联,除非它的操作可能需要很长时间,我想要{ {1}}阻止继续回复其他消息。
通常,任何不阻塞,休眠或执行I / O的工作都可以安全地放在go
块中,而不会对系统的吞吐量产生重大影响。
您可以使用go
向工作人员或工作人员群体提交工作。我几乎不会在>!
块中使用>!!
,因为它可以阻止分配给运行go
块的有限数量的线程之一。
当您需要执行I / O或可能长时间运行的计算时,请使用go
而不是thread
。这与go
非常相似 - 它创建了一个真实的线程 - 但它返回了一个类似future
的频道。
go
是一个较低级别的操作,通常用于"边界" core.async将其连接到传统的基于回调的接口。很少有理由在put!
内使用put!
。
core.async可以支持对线程创建方式的细粒度控制。我在博客文章Parallel Processing with core.async中展示了一些可能性。