加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Clojure – 为什么在阻塞插入到频道时执行挂起? (core.async)

发布时间:2020-12-14 05:30:10 所属栏目:Java 来源:网络整理
导读:请考虑以下代码段: (let [chs (repeatedly 10 chan)] (doseq [c chs] (!! c "hello")) (doseq [c chs] (println (!! c)))) 执行此操作将永久挂起.这是为什么? 如果我做(去(!c“你好”)),它的工作很好. 解决方法 要进行异步放置,请使用clojure.core.async
请考虑以下代码段:
(let [chs (repeatedly 10 chan)]
  (doseq [c chs]
    (>!! c "hello"))
  (doseq [c chs]
    (println (<!! c))))

执行此操作将永久挂起.这是为什么?

如果我做(去(>!c“你好”)),它的工作很好.

解决方法

要进行异步放置,请使用clojure.core.async / put!
(let [chs (repeatedly 10 chan)]
  (doseq [c chs]
    (put! c "hello"))
  (doseq [c chs]
    (println (<!! c))))

这个例子在这个例子中是< !!由于所有必要的投注异步发生,总是会阻止.请注意以下事项:
>阻塞作为不同进程之间的同步约束
>> !!和< !!阻塞主线程. go程序在主线程上运行,但是它们的代码通过宏扩展进行修改,以便执行控制被反转,并且可以通过core.async通道阻塞/缓冲逻辑的规律连续排序执行.这种技术通常被称为IOC(控制反转)状态机.
> ClojureScript只有一个线程.因此,它的core.async的实现甚至不包含> !! /< !!.如果您编写旨在与ClojureScript兼容的代码,则只能从go-routines中的通道或从传递给更高级别函数的派生值中取出!并且总是放在go-routine中或使用put!
是(go(>!ch v))等同于(put!ch v)?

是的,但不一样.放!是一个API包装器,围绕channel.async.impl.protocols / WritePort放置的通道实现!方法. (go(>!ch v))的宏扩展最终在同一个方法调用中发生,但将其包装在许多生成的状态机器代码中,以便可能停止放置操作并暂停执行go程序,直到消费者准备就绪从ch(尝试(宏展开`(go(>!ch v)))自己).产生一个去块只做一个异步放置操作是一种浪费,比调用put更糟糕!马上.去产生并返回一个额外的渠道,你可以把它的身体的结果.这可以让您等待完成执行,您无需在示例中执行(针对异步操作).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读