2 回答
TA贡献1829条经验 获得超13个赞
Dewy Broto 为您的问题提供了很好的解决方案。这是一个简单直接的解决方案,但我想更广泛地评论您如何为不同的问题寻找解决方案。
Go 使用通信顺序进程代数 (CSP) 作为通道、选择和轻量级进程 ('goroutines') 的基础。CSP保证事件的顺序;当您通过做出选择(又名select)这样做时,它只会引入非确定性。有保证的排序有时被称为“先发生”——它使编码比替代(广受欢迎)的非阻塞风格简单得多。它还为创建组件提供了更多空间:通过渠道以可预测的方式与外部世界交互的长期功能单元。
或许关于频道阻塞的讨论在人们学习围棋的方式上设置了心理障碍。我们在 I/O 上阻塞,但我们在通道上等待。如果系统作为一个整体有足够的并行松弛度(即其他活动的 goroutines)来保持 CPU 忙碌,那么等待通道是不会皱眉的。
可视化组件
所以,回到你的问题。让我们从组件的角度考虑它,您有许多需要探索的点来源。假设每个源都是一个 goroutine,然后它在您的设计中形成一个带有输出通道的组件。Go 允许共享通道端,因此许多源可以安全地按顺序将它们的点交错到单个通道上。您无需执行任何操作 - 这就是频道的工作方式。
Dewy Broto 描述的批处理功能本质上是另一个组件。作为一种学习练习,以这种方式表达它是一件好事。批处理组件具有一个点输入通道和一个批次输出通道。
最后,HTTP i/o 行为也可以是一个具有一个输入通道而没有输出通道的组件,仅用于接收整批点然后通过 HTTP 发送它们。
以只有一个来源的简单情况为例,这可能是这样描述的:
+--------+ point +---------+ batch +-------------+
| source +------->-------+ batcher +------->-------+ http output |
+--------+ +---------+ +-------------+
这里的目的是在基本层面描述不同的活动。这有点像数字电路图,这不是巧合。
你确实可以在 Go 中实现它,它会起作用。它甚至可能工作得很好,但在实践中您可能更喜欢通过组合成对的组件来优化它,必要时重复。在这种情况下,很容易将批处理器和 http 输出结合起来,这样做最终会得到 Dewy Broto 的解决方案。
重要的一点是 Go 并发最容易发生
(a)不要预先担心阻塞;
(b)描述需要在相当细粒度的级别上发生的活动(在简单的情况下,您可以在头脑中完成);
(c)如有必要,通过将功能组合在一起进行优化。
我将把更高级的可视化移动通道端(Pi-Calculus)主题作为挑战,其中通道用于将通道端发送到其他 goroutine。
- 2 回答
- 0 关注
- 177 浏览
添加回答
举报