请在2024 Clojure 状态调查中分享您的想法!

欢迎!有关此功能的工作方式,请参阅关于页面以获取更多信息。

+4
core.async

此更改https://github.com/clojure/core.async/commit/3429e3e1f1d49403bf9608b36dbd6715ffe4dd4f 显著改变了管道创建的线程数(0个新线程与N个新线程),在保持独立存在的同时消除了管道和管道阻塞之间的唯一区别,这似乎很奇怪,因此我试图理解其目的。

  1. 我见过 Alex 提到他在管道中发现了阻塞操作的错误,并通过使管道和管道阻塞表现得一样来修复了它,因此我认为这指的是这个提交。

  2. 我不理解的是旧版本中阻塞操作在哪里。我看到可能与之有关的是 processes 函数中使用 >!!,但它在一个缓冲区大小为 1 的通道上只调用一次,这个通道是在立即之前创建的,并在之后立即关闭,因此没有其他操作可以等待它,因此它可能是一个永远不阻塞的 put!

如果 #1 真的是提交背后的原因,我试图根据 #2 理解它,如果 #1 不是提交背后的原因,那么有人知道是什么吗?

如果 #2 直接是错误的,有没有某种方式,在非共享通道(缓冲区有空位时) >! 可以阻塞?

这是关于阻塞 xforms 吗?我以为那是警告消费者。

鉴于 pipeline 现在的行为与 pipeline-blocking 一致,它会被标记为已弃用吗?

1 个答案

+3

被选中
 
最佳答案

作为一般政策,不应在go块的范围内执行阻塞操作,这包括像>!!这样的core.async阻塞操作。所以,是的——这里的问题是管道代码违反了这项政策。在实践中,你在这个特定情况下是正确的,即在一个大小为1的空通道上使用>!!不会阻塞(但仍然违反了意图政策)。

使用put!将是另一种选择,然而这里也存在一个更大的概念问题:管道声称使用“并行度n”。然而,通过将那些任务放入go块中,你实际上受限于go线程池的最大并行度,通常是8,这假设没有任何人使用go块线程池,因此可能甚至少于这个数字。其次,如果用户在管道中做了阻塞操作(他们不应该这么做),那么他们很容易锁定整个系统。

转向使用与管道阻塞相同的策略(使用单独的缓存线程池)可以解决并行性问题。然而,这可能不是这个问题的最后改变——我们可能仍然会转向使用显式的固定大小计算线程池,而不是缓存线程池,这会将它们再次分开。所以,没有废弃任何计划——用户仍然在这里声明了一个产生重大差异的意图。

...