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

欢迎!有关如何使用本站更详细的信息,请参阅关于页面。

+4
core.async

这个更改https://github.com/clojure/core.async/commit/3429e3e1f1d49403bf9608b36dbd6715ffe4dd4f极大地改变了管道创建的线程数量(0个新线程与N个新线程之间),同时去除了管道与管道阻塞之间的唯一区别,虽然它们各自独立存在,这看起来有些奇怪,所以我试图理解其目的。

  1. 我曾看到Alex说他在pipeline的阻塞操作中找到一个bug,并通过使pipeline和pipeline-blocking的行为相同来修复它,所以我认为这指的是这个提交。

  2. 我不明白的是在旧版本中阻塞操作在哪里。我能看到的东西可能就是process函数中对>!!的使用,但它在创建大小为1的缓冲区通道上只调用一次,这个缓冲区通道是在立即创建后立即关闭的,所以没有其他操作可以挂起在它上面,所以它可能就是一个永远不会阻塞的put!

如果#1确实是提交背后的原因,考虑到#2,我并不理解它,如果#1不是提交背后的原因,那么有人知道是什么吗?

是#2直接错误吗?有没有办法使得在带有空间缓冲区的非共享通道上>!!可以阻塞?

这是关于阻塞转换吗?我原以为那是一个公开声明。

因为现在pipeline的行为与pipeline-blocking相同,pipeline会不会被标记为弃用?

1 答案

+3

已选择
 
最佳答案

作为一项一般性政策,不应在 go 块的作用域内执行阻塞操作,这包括与 >!! 这样的 core.async 阻塞操作。因此,是的——这里的問題在于管線代码违反了这一政策。在实践中,你在这个特殊案例中是正确的,即对一个大小为1的空通道使用 >!! 不会阻塞(但仍然违反了意图政策)。

使用 put! 将会是另一个选择,然而这里还有更大的概念性问题。管線声称要使用“并行度 n”。但是,通过将这些任务放入 go 块中,你实际上受到 go 线程池的最大并行度的影响,这通常为8,并且假设没有其他人使用 go 块线程池,所以它可能甚至更少。其次,如果用户在管道中执行阻塞操作(他们不应该这样做),那么他们很容易使整个系统锁定。

通过转向使用与管道阻塞相同的策略(使用单独的缓存线程池)解决了并行性问题。然而,这可能不是这一方面的最后变化——我们可能仍然会切换到使用显式的固定大小计算线程池,而不是缓存线程池,这又会将它们分开。所以,没有计划弃用任何东西——用户仍然在陈述一个在这里产生重要差别的意图。

...