Go Wiki: 使用 sync.Mutex 还是 channel?

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

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

那么应该使用哪种呢?

使用最能表达意图或最简单的。

Go 新手常见的错误是过度使用 channel 和 goroutine,仅仅因为可能,或者因为它很有趣。如果 sync.Mutex 更适合您的问题,请不要害怕使用它。Go 在让您使用最能解决您问题的工具方面是务实的,而不是强迫您使用一种代码风格。

但是,作为一般指南:

ChannelMutex
传递数据所有权,
分发工作单元,
通信异步结果
缓存,
状态

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

Wait Group

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

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

第二种更通用的情况是循环算法,该算法涉及一组 goroutine,它们各自独立工作一段时间,然后在屏障上等待,然后再独立继续。这种模式可能会重复多次。数据可能在屏障事件时交换。这种策略是 批量同步并行 (BSP) 的基础。

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

更多信息


此内容是 Go Wiki 的一部分。