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 提供

本实现的可观测化基于Rich对你问题的回答(来自内部聊天):“打开+空= false,否则 true”,我相信这正是实现并在测试中反映的内容。这比仅在关闭时实现更有意义。

你的评论与可观测化?的其它情况似乎准确,所以我同意这是一个问题。

请具体说明是哪种实现协议?我猜你特别指的是通道和缓冲区。任何线程都可以调用通道。M2MC使用互斥锁保护其内部状态,并将调用向下传递到缓冲区。所有对缓冲区的调用都由通道互斥锁保护。M2MC在put和take列表中入队待处理的put和take操作。这些受限于clojure.core.async.impl.protocols/MAX-QUEUE-SIZE(1024)的固定限制,此时将抛出异常。

0

评论由:alexmiller 提供

在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和timeout都定义在clojure.core.async中,而clojure.core.async依赖于clojure.core.async.impl.channels,因此这里存在循环依赖问题。处理<!!和超时的方法相对简单,可以通过查找delay后面的符号如下

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

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

然而,对于alt!!,我在如何实现等效方面有些困惑,它是一个围绕do-alt和alts!!的宏。

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 提供

新的补丁回归到先前阻塞解引用的实现(基本上是<!!的核心内容)并添加了基于alts的定时解引用的新版本。

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
参考:[https://clojure.atlassian.net/browse/ASYNC-102](https://clojure.atlassian.net/browse/ASYNC-102)(由 stu 报告)
...