2024 Clojure状态调查中分享您的想法!

欢迎!请参阅关于页面了解更多此网站的工作信息。

+2
core.async
  • 每次deref都会从通道中获取一个值
  • 对已关闭通道的deref返回nil
  • 带超时的deref必须要么超时,要么从通道中取得值(不能同时这样做!)!可能只是想要通过var调用alt!!的一些变体。
  • 高效使用内部功能
  • 不要实现IPending/realized,两种解释都相当糟糕

补丁: async-102-2.patch

deref和超时deref的实现(链接:http://dev.clojure.org/jira/browse/ASYNC-102?focusedCommentId=37211&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-37211,概念上简单),但由于存在循环命名空间依赖,实现起来较困难。建议欢迎。

8 个答案

0
_评论来自:stu_

async-102.patch与描述“一个通道在关闭时变为realized”不符——相反,一个通道在当前有可用值时变为realized。这两种解释都似乎有问题,我认为需要对{{realized?}}的定义进行澄清,以支持这个新情况。同时,Clojure中{{realized?}}的其他使用都保证后续的deref将立即被填充,但如果有另一个消费者取走值,通道的情况将不会是这样。

解决此问题后,我需要在审查这个之前为core.async实现协议编写更好的文档字符串。对线程的使用有哪些保证?工作在哪里排队?如果队列满了会发生什么?
0

评论来自:alexmiller

我的realized?实现基于Rich对您问题的回复(来自内部聊天):“open+empty = false,否则为true”,我相信这就是实施的内容,并且在测试中也得到了体现。这也比仅仅在close时实现更有意义。

您的注释与其他realized?的场景似乎很准确,所以我同意这是一个问题。

您能否更具体地说明实施协议的哪个版本?我猜测您具体指的是Channel和Buffer。任何线程都可以调用Channel。M2MC使用互斥锁保护其内部状态,并将调用转发到Buffer。所有对Buffer的调用都受到channel互斥锁的保护。M2MC将在puts和tapes列表中排队等待的puts和tapes。这些受限于固定的限制clojure.core.async.impl.protocols/MAX-QUEUE-SIZE(1024),超过这个限制将抛出异常。

0

评论来自:alexmiller

使用现有的async构造在ManyToManyChannel中使用IDeref和IBlockingDeref的概念实现相对简单。

`
(deftype ManyToManyChannel
#_existing_code...
IDeref
(deref [this] (<!! this))

IBlockingDeref
(deref [this ms timeoutValue]

(alt!!
  this ([val _] val)
  (timeout ms) timeoutValue)))

`

然而,M2MC定义在clojure.core.async.impl.channels中。<!!, alt(image: ), 和 timeout都是在clojure.core.async中定义的,它依赖于clojure.core.async.impl.channels,因此这里存在循环依赖问题。<!! 和 timeouts通过查找delay后的var很容易处理,比如这样

`
(def ^:private <!!' (delay (find-var 'clojure.core.async/<!!)))

;; 然后
IDeref
(deref [this] (@<!!' this))
`

然而,我有点难以处理alt!!的类似实现,它是一个围绕do-alt和alts(image: )的宏。

0

评论者:gshayban

不要依赖于解决循环依赖。相反,创建一个共享的alt标志并将两个处理程序(link: 1)入队。fret将交付一个承诺,然后取消引用承诺。

(link: 1) https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L230-L231

0

评论来自:alexmiller

新补丁回到之前阻塞deref的实现(基本上是<!!的来源)并添加了基于alts的超时deref的新版本。

0

评论由:fogus 创建

然而,我对如何用
alt!!(这是一个围绕 do-alt 和 alts!! 的宏)来等效处理感到困惑。

我想知道以下方法是否可以解决 alts!! 的问题:

(def ^:private ^:macro alts!!' (deref (find-var 'clojure.core.async/alts!!)))

然后,在 IBlockingDeref 的 deref 实现中使用它。按照目前的情况,由于它使用了某些 core.async 实现的细节(确实,是相同的代码),因此很难理解所编写的代码。而你的 IBlockingDeref.deref 的实现非常清晰,然而由循环依赖产生的实现相对不那么清晰。我不想重复这一点(但我似乎非得说),alts!! 是一个清晰的实现,但使用内部细节会使问题复杂化。如果可能的话,我更喜欢清晰度。

话虽如此,作为一个人类宏展开器,我最终理解了实现方法。

0

评论来自:alexmiller

这对我来说似乎不起作用。如果你有一些有效的公式,那将非常棒!

0
...