gpt4 book ai didi

clojure - 在 clojure core.async go-loop 中工作的方式有哪些权衡?

转载 作者:行者123 更新时间:2023-12-02 17:16:29 25 4
gpt4 key购买 nike

当我编写更多 core.async 代码时,出现的一种非常常见的模式是循环,它在一系列 channel 上进行切换并执行一些工作来响应消息,例如:

(go-loop [state {}]
(let [[value task] (alts! tasks)]
...work...
(recur state))

尽管如此,我觉得我并不理解实际完成这项工作的各种方法的权衡,所以我想我应该尝试在这里探索它们。

  • 内联或通过调用函数:这会阻止循环继续,直到工作完成。由于它位于 go block 中,因此不想执行 I/O 或锁定操作。
  • >!发送给工作人员监控的 channel 的消息:如果 channel 已满,则会通过 parking 来阻塞循环,直到 channel 有容量为止。这允许线程执行其他工作并允许背压。
  • !!一条消息:如果 channel 已满,则会通过休眠运行 go 循环的线程来阻塞。这可能是不可取的,因为 Go 线程是严格有限的资源。
  • >!另一个 go block 中的消息:这几乎会立即成功,除非没有可用的 go 线程。相反,如果 channel 已满并且消耗缓慢,则可能会在短时间内导致系统的 go 线程匮乏。
  • !!带有线程 block ​​的消息:与 go block 类似,但消耗系统线程而不是 go 线程,因此上限可能更高
  • 放!一条消息:尚不清楚权衡是什么
  • 在未来调用工作函数:将工作交给 clojure 代理池中的线程来完成,允许 go 循环继续。如果输入速率超过输出速率,代理池队列就会无限增长。

此摘要正确且全面吗?

最佳答案

如果要完成的工作完全受CPU限制,那么我可能会在go block 中内联完成它,除非它是一个可能需要很长时间的操作并且我想要 >go 阻止继续响应其他消息。

一般来说,任何不阻塞、 sleep 或执行 I/O 的工作都可以安全地放入 go block 中,而不会对系统的吞吐量产生重大影响。

您可以使用 >! 将工作提交给一个工作人员或工作人员池。我几乎不会在 go block 中使用 >!!,因为它会阻塞分配给正在运行的 go block 的有限数量的线程之一。

当您需要执行 I/O 或可能需要长时间运行的计算时,请使用 thread 而不是 go。这与 future 非常相似 - 它创建一个真正的线程 - 但它返回一个类似 go 的 channel 。

put! 是一个较低级别的操作,通常在 core.async 的“边界”使用,将其连接到传统的基于回调的接口(interface)。很少有理由在 go 中使用 put!

core.async 可以支持对线程创建方式的细粒度控制。我在博客文章 Parallel Processing with core.async 中演示了一些可能性。 .

关于clojure - 在 clojure core.async go-loop 中工作的方式有哪些权衡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24915034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com