Go Wiki:使用 sync.Mutex 还是通道?

Go 的座右铭之一是“通过通信共享内存,而不是通过共享内存进行通信。”

话虽如此,Go 确实在 sync 软件包 中提供了传统的锁定机制。大多数锁定问题都可以使用通道或传统锁来解决。

那么你应该使用哪一个呢?

使用最具表现力且/或最简单的那个。

Go 新手常犯的一个错误是过度使用通道和 goroutine,仅仅因为有可能,或者因为很有趣。如果你发现 sync.Mutex 最适合你的问题,请不要害怕使用它。Go 的实用性在于让你可以使用最能解决你问题的工具,而不是强迫你使用一种编码风格。

不过,作为一般指南

通道互斥锁
传递数据所有权,
分配工作单元,
异步通信结果
缓存,
状态

如果您发现您的 sync.Mutex 锁定规则变得过于复杂,请自问使用通道是否会更简单。

等待组

另一个重要的同步原语是 sync.WaitGroup。这些允许协作 goroutine 在独立继续进行之前共同等待阈值事件。这通常在两种情况下很有用。

首先,在“清理”时,可以使用 sync.WaitGroup 来确保所有 goroutine(包括主 goroutine)在干净终止之前等待。

第二个更通用的情况是一组 goroutine 的循环算法,它们都独立工作一段时间,然后在继续独立进行之前都等待一个屏障。此模式可能会重复多次。数据可以在屏障事件处交换。此策略是大规模同步并行(BSP)的基础。

通道通信、互斥锁和等待组是互补的,可以组合使用。

更多信息


此内容是Go Wiki的一部分。