Clojure core.async 放!对块
Clojure core.async put! versus go block
我在这里阅读了这篇关于 core.async 的精彩文章:
http://www.core-async.info/reference/primitives
我正在努力理解 put 的内部机制!去。我的理解是:
- 放!是异步的,可以接受回调。这在简单的场景中效果很好,但你可能会以回调地狱结束。
- go 修复了回调地狱,并允许以同步方式编写异步代码。
- go 利用轻量级线程池,并利用停车来实现并发。
- go 使用有限状态机
我不明白:
- 怎么放!实现异步?它也使用线程池吗?
- 确实放!也使用停车位?
- 有限状态机在 go 块中的作用是什么?是什么让停车成为可能?
- 我应该总是尝试使用 put!而不是去,因为它更便宜?那样的话,是不是意味着put!实现与 go 完全相同的并发优势,而 go 仅在我想推理复杂的异步代码时使用?
非常感谢您解开这些谜团。
如果您想了解 core.async 通道的工作原理,没有比 Rich Hickey 的 EuroClojure 2014 演示文稿更好的来源了:Implementation details of core.async channels.
关于您的具体问题:
如果 put!
没有立即被接受,它会将一个挂起的放置(要放置在通道上的值 + put!
回调)放在通道内部的队列中渠道。请注意,如果队列中没有空间(最大容量目前固定为 1024),则会抛出异常。
如果 (1) put 未立即被接受或 (2) 显式 false
作为最终参数传递给 put!
调用,则将在池线程上调用回调(此参数称为 on-caller?
,有关详细信息,请参阅 put!
的文档字符串)。
"Parking",在 go
块的上下文中,指的是通过记录其当前状态的某些细节来暂停执行 go
块的状态机,并且将它们保存在一个通道或多个通道中,以便以后可以重新启动。 (请注意,这种安排意味着如果所有持有对挂起 go
块的引用的通道都被 GC'd,则 go
块本身也可以被 GC'd。)在其他上下文中它类似地指代将控制线程置于假死状态。 put!
只是一个函数(好吧,它由协议方法支持,但是 that 只是一个协议方法),所以这个概念不适用。
是的。它基本上遍历 go
块中的代码,可能会在控制达到某个 "custom terminals" 时暂停它(<!
、>!
、alt!
)。
不一定,你应该首先考虑内部队列溢出的风险(见上文第1点)。
我在这里阅读了这篇关于 core.async 的精彩文章:
http://www.core-async.info/reference/primitives
我正在努力理解 put 的内部机制!去。我的理解是:
- 放!是异步的,可以接受回调。这在简单的场景中效果很好,但你可能会以回调地狱结束。
- go 修复了回调地狱,并允许以同步方式编写异步代码。
- go 利用轻量级线程池,并利用停车来实现并发。
- go 使用有限状态机
我不明白:
- 怎么放!实现异步?它也使用线程池吗?
- 确实放!也使用停车位?
- 有限状态机在 go 块中的作用是什么?是什么让停车成为可能?
- 我应该总是尝试使用 put!而不是去,因为它更便宜?那样的话,是不是意味着put!实现与 go 完全相同的并发优势,而 go 仅在我想推理复杂的异步代码时使用?
非常感谢您解开这些谜团。
如果您想了解 core.async 通道的工作原理,没有比 Rich Hickey 的 EuroClojure 2014 演示文稿更好的来源了:Implementation details of core.async channels.
关于您的具体问题:
如果
put!
没有立即被接受,它会将一个挂起的放置(要放置在通道上的值 +put!
回调)放在通道内部的队列中渠道。请注意,如果队列中没有空间(最大容量目前固定为 1024),则会抛出异常。如果 (1) put 未立即被接受或 (2) 显式
false
作为最终参数传递给put!
调用,则将在池线程上调用回调(此参数称为on-caller?
,有关详细信息,请参阅put!
的文档字符串)。"Parking",在
go
块的上下文中,指的是通过记录其当前状态的某些细节来暂停执行go
块的状态机,并且将它们保存在一个通道或多个通道中,以便以后可以重新启动。 (请注意,这种安排意味着如果所有持有对挂起go
块的引用的通道都被 GC'd,则go
块本身也可以被 GC'd。)在其他上下文中它类似地指代将控制线程置于假死状态。put!
只是一个函数(好吧,它由协议方法支持,但是 that 只是一个协议方法),所以这个概念不适用。是的。它基本上遍历
go
块中的代码,可能会在控制达到某个 "custom terminals" 时暂停它(<!
、>!
、alt!
)。不一定,你应该首先考虑内部队列溢出的风险(见上文第1点)。