1。运行每个示例:不要只阅读代码。输入它,运行它,然后观察其行为。⚠️ 这个系列如何进行?
2。实验和打破常规: 删除睡眠并看看会发生什么,更改通道缓冲区大小,修改 goroutine 计数。
打破东西会教你它们是如何工作的
3。关于行为的原因: 在运行修改后的代码之前,尝试预测结果。当您看到意外行为时,请停下来思考原因。挑战解释。
4。建立心理模型:每个可视化代表一个概念。尝试为修改后的代码绘制自己的图表。
在上一篇文章中,我们探讨了管道并发模式,这是 扇入 和 扇出 并发模式的构建块。您可以在这里阅读:
在这篇文章中,我们将介绍扇入和扇出模式,并尝试将它们可视化。因此,让我们做好准备,因为我们将亲手完成整个过程。
扇入扇出模式是管道模式的自然演变。虽然管道通过阶段顺序处理数据,但扇入扇出引入了并行处理功能。让我们想象一下这种演变是如何发生的:
想象一下繁忙时段的餐厅厨房。当订单进来时,多名厨师同时处理不同的菜肴(扇出)。当他们完成菜肴后,他们会聚集在服务柜台(扇入)。
扇出是将工作分配给多个 goroutine 来并行处理数据。可以将其视为将一项大任务分成可以同时完成的较小部分。这是一个简单的例子:
func fanOut(input <h3> 了解扇入 </h3> <p>扇入与扇出相反 - 它将多个输入通道合并为一个通道。它就像一个漏斗,将所有工作人员的结果收集到一个流中。以下是我们的实现方式:<br> </p> <pre class="brush:php;toolbar:false">func fanIn(inputs ... <p>让我们用一个并行处理数字的完整示例将它们放在一起:<br> </p> <pre class="brush:php;toolbar:false">func main() { // Create our input channel input := make(chan int) // Start sending numbers go func() { defer close(input) for i := 1; i <h2> 为什么要使用扇入扇出模式? </h2> <p><strong>最佳资源利用</strong></p> <p>该模式自然地在可用资源之间分配工作,这可以防止资源闲置,从而最大限度地提高吞吐量。<br> </p> <pre class="brush:php;toolbar:false">// Worker pool size adapts to system resources numWorkers := runtime.NumCPU() if numWorkers > maxWorkers { numWorkers = maxWorkers // Prevent over-allocation }
通过并行化提高性能
func fanOut(tasks []Task) { numWorkers := runtime.NumCPU() // Utilize all available CPU cores workers := make([] <h2> 现实世界的用例 </h2> <p><strong>图像处理管道</strong></p> <p>这就像我们的管道模式帖子的升级,我们需要更快地处理,并且每个进程都有专用的 go 例程:</p><p><img src="https://img.php.cn/upload/article/000/000/000/173625991579012.png" alt="Go 中的扇入扇出并发模式:综合指南 processing pipeline with fan in and fan out pattern" loading="lazy" style="max-width:90%" style="max-width:90%"></p> <p><strong>网络抓取管道</strong><br> 网页抓取是扇入扇出的另一个完美用例。</p> <p><img src="https://img.php.cn/upload/article/000/000/000/173625991836275.png" alt="Web scraping is another perfect use case for fan-in fan-out" loading="lazy" style="max-width:90%" style="max-width:90%"></p> <p>扇入扇出模式在这些场景中确实很出色,因为它:</p>
尝试在管道开始之前或开始时执行各种验证,以确保它不会失败,因为它可以防止将资源浪费在稍后会失败的无效工作上。这在扇入扇出模式中尤其重要,因为无效数据可能会阻塞工作人员或浪费并行处理能力。
但这并不是一个硬性规则,很大程度上取决于业务逻辑。以下是我们如何在现实世界的示例中实现它:
func fanOut(input <p>和<br> </p> <pre class="brush:php;toolbar:false">func fanIn(inputs ... <p>注意!一个工人犯错误,另一个工人不会停止,他们继续处理,这给我们带来了第二个原则</p> <h3> 隔离故障:一名员工的错误不应影响其他员工 </h3> <p>在并行处理系统中,一项糟糕的任务不应导致整个系统崩溃。每个工人都应该是独立的。<br> </p> <pre class="brush:php;toolbar:false">func main() { // Create our input channel input := make(chan int) // Start sending numbers go func() { defer close(input) for i := 1; i <h4> 资源清理:正确清理错误 </h4> <p>并行处理中的资源泄漏可能会迅速升级为系统范围的问题。适当的清理至关重要。</p> <hr> <p>我们对扇入和扇出模式的深入研究到此结束!接下来,我们将探讨<strong>工作池并发模式</strong>,我们在这篇文章中有所了解。就像我说的,我们正在逐步清除依赖关系,然后再进行下一个。</p> <p>如果您发现这篇文章有帮助,有任何疑问,或者想分享您自己的这种模式的经验 - 我很乐意在下面的评论中听到您的意见。您的见解和问题有助于使这些解释对每个人来说都更好。</p> <p>如果您错过了 Golang 的 goroutine 和通道的视觉指南,请在此处查看:</p> <div> <div> <img src="https://img.php.cn/upload/article/000/000/000/173625990185651.png" alt="Go 中的扇入扇出并发模式:综合指南" loading="lazy"> </div> <div> <h2>理解和可视化 Golang 中的 Goroutines 和 Channel</h2> <h3>Souvik Kar Mahapatra ・ 2024 年 12 月 20 日</h3> <div> #去 #编程 #学习 #教程 </div> </div> </div> <p>请继续关注更多 Go 并发模式! ?</p> <p><img src="https://img.php.cn/upload/article/000/000/000/173625992371812.gif" alt="Go 中的扇入扇出并发模式:综合指南" loading="lazy" style="max-width:90%" style="max-width:90%"></p>
以上是Go 中的扇入扇出并发模式:综合指南的详细内容。更多信息请关注PHP中文网其他相关文章!