【问题标题】:go block hangs indefinitely with core.syncgo 块无限期挂起与 core.sync
【发布时间】:2015-05-20 16:42:15
【问题描述】:

代码如下:

(ns typed-clj-test.async
  (:require [clojure.core.async
             :as a
             :refer [>! <! >!! <!!
                     go chan buffer
                     close! thread
                     alts! alts!! timeout]]))

(def echo-buffer (chan 2))
(go (do (<! (timeout 5000))
        (println (<! echo-buffer))))
(>!! echo-buffer "msg1")
(>!! echo-buffer "msg2")
(>!! echo-buffer "msg3")
(>!! echo-buffer "msg4")

在 nrepl 中打印 msg1 后,这将永远挂起:

typed-clj-test.async=> (def echo-buffer (chan 2))
#'typed-clj-test.async/echo-buffer
typed-clj-test.async=> (go (do (<! (timeout 5000))
                  #_=>         (println (<! echo-buffer))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@6cc648a>
typed-clj-test.async=> (>!! echo-buffer "msg1")
true
typed-clj-test.async=> (>!! echo-buffer "msg2")
true
typed-clj-test.async=> (>!! echo-buffer "msg3")
msg1
true
typed-clj-test.async=> (>!! echo-buffer "msg4")

【问题讨论】:

    标签: asynchronous clojure core.async


    【解决方案1】:

    您只会从回显缓冲区中获取第一条消息,并且由于缓冲区大小为 2,因此尝试将第四条消息添加到缓冲区将阻塞,直到从缓冲区中删除另一个值(这永远不会发生)。

    换句话说,你似乎期望那个

    (go (do (<! (timeout 5000))
            (println (<! echo-buffer))))
    

    循环,但不会。

    这里是如何使它工作:

    (def echo-buffer (chan 2))
    (go (do (loop [i 0]
              (<! (timeout (* 100 (rand-int 20))))
              (println (<! echo-buffer))
              (recur i))))
    (>!! echo-buffer "msg1")
    (>!! echo-buffer "msg2")
    (>!! echo-buffer "msg3")
    (>!! echo-buffer "msg4")
    

    【讨论】:

      猜你喜欢
      • 2016-01-25
      • 2017-06-29
      • 2011-05-07
      • 2021-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-29
      • 2019-08-01
      相关资源
      最近更新 更多