Mutex和channel 都可以在并发环境下对资源进行保护,避免竞态, channel 在 golang 中一直被追捧,但是既然都能解决问题,但为什么还要弄两个东西呢?
查阅一些文章,发现有些时候对于channel过于追捧了。有时候该用Mutex 还是要用Mutex的,不要为了用channel 而用channle, 需要区分不同的场景
我们以一个例子,在多个协程下,对公共变量执行减一操作
有一个公共变量total 为1000, 之后启1000个协程,每个协程对total 进行减一操作,我们想得到0的结果,但是由于多个协程同时操作一个变量,在没有加锁的情况,最后得到的结果很大情况下不为0的,且每次的结果也都不太一样。
使用锁Mutex
由于存在对同一个资源进行操作的情况,所以需要加上锁
lock.Lock()
这次由于加了锁,最后输出的结果为0 了
使用通道channel
在匿名函数中使用channel 对共享数据进行保护
Mutex和channel 的选择
- Channel 是 Go 中的高级概念,Go 中某些程序仅使用 Mutex, Go 的 Channel 很吸引人因为它们提供了内置的线程安全性,并鼓励对共享的关键资源进行单线程访问。 但是与 Mutex 相比,Channel 会导致性能下降。 当只需要锁定少量共享资源时,使用 Mutex 非常有用。 如果 Mutex 很适合你的需求请放心使用 sync.Mutex。
- 如果需要将数据资源在各个协程间进行流动那么需要使用channel
- channel 关注数据流动,如果任务处理模型中存在数据流动,使用channel 解决;
- 数据的控制权需要在多个gorutine 中传递, 使用 channel 处理;