2024 Clojure调查问卷中分享您的想法!

欢迎!有关此工作方式的信息,请参阅关于页面

+2
core.async
  • 每次 deref 都将从一个通道中获取一个值
  • 从一个关闭的通道 deref 返回 nil
  • 带有超时的 deref 必须要么超时,要么从通道中获取值(不两个都!)。您可能只需通过 var 调用 alt!! 的某个变体即可。
  • 高效使用内部机制
  • 不要实现 IPending/realized,这两种解释都不太好。

补丁: async-102-2.patch

deref 和 timed 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?}} 的定义需要澄清以支持这种新情况。Clojure 中 {{realized?}} 的其他使用都保证连续 derefs 将立即填满,但这对于通道来说将不会成立,如果另一个消费者获取了值。

一旦解决这个问题,我需要在筛选之前为 core.async 实现协议提供更好的文档字符串。关于线程的使用有哪些保证?工作在哪里入队,队列满了会发生什么?
0

评论由:alexmiller 提供

我的实现“ realized? ”基于Rich对您的提问(来自内部聊天)的回答:“开+空ráfne false,否则 true”,我相信这就是实现,并在测试中得到体现。这也比我只关注关闭时实现更合理。

您的评论与其他“realized? ”的情况似乎准确,因此我同意这确实是一个问题。

您能更具体地说明您指的是哪个实现协议吗?我猜您特别指的是Channel和Buffer。任何线程都可以调用Channel。M2MC使用互斥锁保护其内部状态,并将调用转发到Buffer。所有对缓冲区的调用都由Channel互斥锁保护。M2MC将待处理的put和take操作入队到puts和takes列表中。这些操作受限于固定的限制clojure.core.async.impl.protocols/MAX-QUEUE-SIZE(1024),到那时将抛出异常。

0

评论由:alexmiller 提供

在ManyToManyChannel上使用现有异步构造函数实现IDeref和IBlockingDeref的概念实现相对简单

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

IBlockingDeref
(deref [this ms timeoutValue]

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

`

然而,M2MC定义在clojure.core.async.impl.channels中。

`
(def ^:private

;;然后
IDeref
(deref [this] (@ `

然而,我在如何做等效的alt!!上有点困惑,这是一个围绕do-alt和alts(image: )的宏。

0

由:gshayban提出评论

不要依赖于解决循环依赖。相反,创建一个共享的alt标志并将两个处理器入队(链接:1)。fret将传递一个承诺,然后取消引用该承诺。

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

0

评论由:alexmiller 提供

新的补丁回到了之前的阻塞取消引用实现(基本上是

0

由:fogus提出评论

然而,我在如何做等效的
alt!!,它是对do-alt和alts!!的宏封装。

我想知道下面的方法是否能解决alts!!问题

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

然后在IBlockingDeref的内部实现中使用它。就目前代码而言,由于其使用了某些核心async的实现细节(实际上,是相同的代码),所以很难理解。而你对IBlockingDeref.deref的实现非常清晰,但是由于循环依赖,这种实现则不那么明显。不要过分强调这一点(我似乎一直在强调),但alts!!对这一实现是清晰的,但使用内部细节则让事情复杂。如果我可以做主,我更希望看到清晰性。

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

0
by

评论由:alexmiller 提供

这个方法似乎不起作用。如果你有其他有效的方法,那就太好了!

0
by
参考:[https://clojure.atlassian.net/browse/ASYNC-102](https://clojure.atlassian.net/browse/ASYNC-102)(由stu报告)
...