Mutex和channel 都可以在并发环境下对资源进行保护,避免竞态, channel 在 golang 中一直被追捧,但是既然都能解决问题,但为什么还要弄两个东西呢?

查阅一些文章,发现有些时候对于channel过于追捧了。有时候该用Mutex 还是要用Mutex的,不要为了用channel 而用channle, 需要区分不同的场景

我们以一个例子,在多个协程下,对公共变量执行减一操作

有一个公共变量total 为1000, 之后启1000个协程,每个协程对total 进行减一操作,我们想得到0的结果,但是由于多个协程同时操作一个变量,在没有加锁的情况,最后得到的结果很大情况下不为0的,且每次的结果也都不太一样。

使用锁Mutex

由于存在对同一个资源进行操作的情况,所以需要加上锁

lock.Lock()

这次由于加了锁,最后输出的结果为0 了

使用通道channel

在匿名函数中使用channel 对共享数据进行保护

Mutex和channel 的选择

  1. Channel 是 Go 中的高级概念,Go 中某些程序仅使用 Mutex, Go 的 Channel 很吸引人因为它们提供了内置的线程安全性,并鼓励对共享的关键资源进行单线程访问。 但是与 Mutex 相比,Channel 会导致性能下降。 当只需要锁定少量共享资源时,使用 Mutex 非常有用。 如果 Mutex 很适合你的需求请放心使用 sync.Mutex。
  2. 如果需要将数据资源在各个协程间进行流动那么需要使用channel
  3. channel 关注数据流动,如果任务处理模型中存在数据流动,使用channel 解决;
  4. 数据的控制权需要在多个gorutine 中传递, 使用 channel 处理;

参考