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

欢迎!请参阅关于页面获取有关操作方式的一些更多信息。

0
引用、代理、原子操作

我了解一点Lisp,但Clojure感觉有点不同

(defn mojorate []
  (let [v (vec (range 1 11))
        max (- (count v) 1)
        atomix (atom [])
        chanl (async/chan)]
    (println v)
    (loop [i 0]
      (async/go
        (>! chanl (swap! atomix conj (/ (get v i) 2))))
      (if (= i max)
        (do (<!! (async/go (<! chanl)))
          (async/close! chanl)
          @atomix)
        (recur (inc i))))))

这只是对channel、atom loop/recur等的一个练习。

你能这样做吗?

我不太清楚你在问什么——你能详细说明一下吗?
它如预期那样运行,但我尚不确定这是否:1. 传统的;2. 最佳实践;3. 或有更好的方法。
“预期”是什么意思?函数* supposed*要做什么?当运行它时,我在不同的运行中看到不同的结果产出,所以我无法完全推断你真正需要的是什么。
我一直得到
testomato.core> (mojorate)
[1 2 3 4 5 6 7 8 9 10]                                                                      
[1/2 1 3/2 2 5/2 3 7/2 9/2 5]

这个代码片段向一个通道发送10个数字,并获取它们——除以二。

1 答案

+1

你的goroutine块太多了,不仅在代码中数量太多,而且执行的goroutine也太多。循环中的第一个goroutine块不会阻塞——它会立即继续执行。不能保证在相同的块再次执行之前,之前的块已经有足够的时间将值放入通道中。这是一个竞争条件。

为了证实这一点,只需运行此代码: (set (repeatedly 10000 mojorate))。如果所有得到的结果都是只有一个元素的一组,请增加这个数字。

这个代码片段向一个通道发送10个数字,并获取它们——除以二。

句子的前半部分是函数用户不关心的实现细节。如果你需要的只是从一个1/2开始的10个数字的向量,那么当然就是(mapv #(/ % 2) (range 1 11))

如果你需要其他东西,请详细描述,这样我们就不至于陷入“XY问题”。原始函数可以以多种方式重写——如果你的实际问题需要特定内容,那么所有这些方法都可能不正确。

我试图熟悉这个概念。并且我意识到mapv是一个更紧密的方案。用简单的算术来说明这类事情并不罕见。以下是用Common Lisp的一个例子:

(let ((channel (make-channel)))
  (submit-task channel '+ 3 4)
  (receive-result channel))

但我可以确认你预测的结果:经过10.000次重复,我得到以下结果

#{[1/2 1 3/2 2 5/2 3 7/2 4 9/2 5]
  [1 3/2 2 5/2 3 7/2 4 9/2 5 1/2]
  [1/2 1 3/2 2 5/2 3 7/2 4 9/2]
  [1/2 1 2 5/2 3 7/2 4 9/2 5 3/2]}
by
据我所知,Common Lisp中的channels和`clojure.core.async`中的channels并不相同。它们更像是一种与特定线程进行通信的方式。在Clojure中,如果你想在一个单独的线程中运行一系列计算,最好只使用`future`或`pmap`(尽管通常建议避免使用`pmap`,而使用其他可控制的方法)。在Clojure中,异步channel在你想从一个位置喂入值,可能在第二个位置对它们进行一些计算,并在第三个位置接收结果,而这些位置实际上可能彼此不了解的情况下非常有用。例如,生产者可能使用`(a/to-chan! (range 1 11))`,转换者可能使用`(a/map #(/ % 2) [channel])`,而消费者可能使用`(a/go (let [all-values (a/<! (a/into [] transformed-channel))] ...))`。
by
当然,Clojure中的channels远不止这些。它们支持不同的缓冲策略,允许进行背压,可以静态或动态地组合和分离channel...
by
reshown by
谢谢。我现在开始清楚看到这一点了。我确实没有看到竞态条件。
...