在Go中使用频道而不是静音的并发控制具有植根于其设计和使用模式的基本差异的几种绩效含义。
GO中的频道体现了通话风格的并发风格,其中通过在Goroutines之间发送和接收消息来明确传输数据所有权。频道通过阻止发件人直到接收器准备就绪而提供同步,或者如果存在缓冲区,则可以缓冲消息。该设计在数据交换上实施了一种序列化形式,使频道非常表达用于建模涉及协调,分布式工作或事件通知的并发工作流程。
另一方面,Mutexes(来自同步软件包)是较低的原始图,以保护多个Goroutines访问的共享内存。通过锁定和解锁关键部分来协调访问,如果使用读取词语,则允许多个读者或单个作者进行访问。他们以最小的开销有效地保护内部状态,但需要仔细注意以避免僵局或比赛条件。
从性能的角度来看,在保护共享可变状态时,静音通常胜过频道,因为:
- 静音是轻巧的,并且针对最小的高架锁定临界部分进行了优化。
- 在GO的运行时,静音中的无锁/解锁路径非常有效。
- 静音避免在频道通信中固有的额外复制或数据传输。
相比之下,通道涉及用于Goroutine同步和数据传递的运行时调度开销。当数据通过频道传递时,它可能会产生复制成本,并且当Goroutines块等待发送或接收时发生上下文开关。对于简单的共享状态保护,频道可能比静音速度明显慢,通常会根据争夺和工作量多次慢。
但是,在涉及的情况下,频道在涉及以下方面的情况下发光。
- 异步协调多个goroutines。
- 通过自然所有权转移语义分发工作单元。
- 串行通信的事件驱动或管道体系结构可提高安全性和代码清晰度。
当测量简单共享变量上同步的原始吞吐量时,由于缺乏强制性数据交接语义的合作锁定方法,基准测量的静音始终比通道快几倍。
内部实现也有所不同:GO中的通道使用一种形式的Futex,涉及更复杂的同步逻辑,并在goroutines之间进行等待队列和信号传导,而静音是更简单的锁定原始词,具有快速的路径,用于无害方案。
他们之间的选择应考虑并发的本质:
- 使用静音剂来保护共享内存的关键部分,需要快速,频繁访问。
- 当您需要协调异步工作流程或在Goroutines之间安全转移所有权时,请更喜欢频道。
过度使用用于数据保护的渠道可能会导致复杂且效率低下的设计,而误解时有时会在锁定规则过于复杂时增加复杂性,在这种情况下,频道可能会简化推理。
总而言之,主要的绩效含义是,静音通常为保护共享状态提供卓越的原始效率,而渠道为通过交流来协调并发提供了更安全,更具表现力但可能更慢的手段。这种权衡会影响GO应用程序中的吞吐量,延迟和可扩展性。
更详细的点:
- 无偶像的静音锁/解锁接近零开销,通常在无内核参与的情况下执行,为低竞争工作负载提供出色的性能。
- 在高度争论下,静音可能会遭受锁锁的障碍,但由于频道会更频繁地阻止和唤醒通道,但仍经常超越频道。
- 频道由于阻止语义和调度成本而增加了开销,缓冲尺寸会影响吞吐量和延迟。
- 静音通过锁定临界部分保护;通道强行序列化通信,这可能会影响并发的吞吐量,具体取决于工作负载模式。
- 频道在内部使用缓冲队列的双重计数信号量实现同步,使它们比静音更重。
- 在Go进行协调时,频道是惯用的,在goroutines自然通信的情况下,但是当需要更简单,高性能的锁定保护时,首选静音。
在实际应用中,决定使用频道与静音的决定不仅取决于原始性能,还取决于代码的清晰度,正确性以及并发模型对问题域的适用性。在现实工作负载下进行基准测试对于做出明智的选择至关重要。
最后,与允许并发读取时相比,RWMUTEX变体可以在读取工作负载中提供改进的性能,而序列化写入,如果没有复杂的模式,场景通道就无法在本地优化。