Clojure core.async把!与阻止

Nic*_*Dao 6 clojure core.async

我在这里读到了关于core.async这篇伟大的文章:

http://www.core-async.info/reference/primitives

我很难理解put的内部机制!去.我明白那个:

  1. 放!是异步的,可以接受回调.这在简单的场景中效果很好,但你可以在回调地狱中结束.
  2. go修复了回调地狱,并允许以同步方式编写异步代码.
  3. go利用轻量级线程池,并利用停车来实现并发.
  4. go使用有限状态机

我不明白:

  1. 怎么放!实现异步?它是否也使用线程池?
  2. 放!还用停车?
  3. 有限状态机在go块中的作用是什么?它是什么使停车?
  4. 我应该总是尝试使用put!而不是因为它更便宜?在那种情况下,这是否意味着放!实现与go完全相同的并发性,只有当我想推理复杂的异步代码时才会使用它?

非常感谢你揭开那些神秘面纱.

Mic*_*zyk 11

如果你想了解core.async频道是如何工作的,那么没有比Rich Hickey的EuroClojure 2014演示文稿更好的来源:core.async频道的实现细节.

至于你的具体问题:

  1. 如果put!未立即接受,它把待处理的put(被放通道+上的值put!上内部的信道队列的回调).请注意,如果队列中没有空间,则会抛出异常(最大容量当前固定为1024).

    如果(1)不立即接受put,或者(2)将explicit false作为put!调用的最后一个参数传入(调用此参数on-caller?,请参阅put!文档字符串以获取详细信息),将在池化线程上调用回调.

  2. go块的上下文中,"停放" 是指go通过记录其当前状态的某些细节并将它们保存在通道或可能的几个通道中来暂停执行块的状态机,以便以后可以重新启动它.(请注意,这种安排意味着如果所有持有对挂起go块的引用的通道都是GC,则go块本身也可以是GC.)在其他情况下,它同样指的是将控制线程置于暂停状态动画.put!仅仅是一个函数(当然,它是由一个协议方法的支持,但随后仅仅是一个协议方法),这样的概念并不适用.

  3. 是.它基本上通过在代码步骤go块中,当控制到达一定的"定制端子"(可能是悬浮它<!,>!,alt!).

  4. 不一定,您应该首先考虑内部队列溢出的风险(参见上面的第1点).