在过去的几周里,我一直在思考一个(不那么简单的)问题:
什么时候使用sync.Mutex
最好,反之,什么时候使用chan
最好?
看起来,对于很多问题,两种策略都是可以互换的- * 而这正是问题所在!*
使用Golang文档中的this video。下面,我冒昧地在playground中口述了代码,并将其转换为sync.Mutex
的等价物。
在真实的世界中遇到的某个问题是否值得使用另一个?
备注:
- 我是chan的超级粉丝,很难想出一个更优雅的sync. Mutex实现。
- 值得注意的是,
chan
实现在同一时间内做的工作更多(达到12)*
Playground:
使用chan
执行Ping/pong操作:
package main
import (
"fmt"
"time"
)
type Ball struct { hits int }
func main() {
table := make(chan *Ball)
go player("ping", table)
go player("pong", table)
table <- new(Ball)
time.Sleep(1 * time.Second)
<-table
}
func player(name string, table chan *Ball) {
for {
ball := <-table
ball.hits++
fmt.Println(name, ball.hits)
time.Sleep(100 * time.Millisecond)
table <- ball
}
}
使用sync.Mutex
执行Ping/pong操作:
package main
import (
"fmt"
"time"
"sync"
)
type Ball struct { hits int }
var m = sync.Mutex{}
func main() {
ball := new(Ball)
go player("ping", ball)
go player("pong", ball)
time.Sleep(1 * time.Second)
}
func player(name string, ball *Ball) {
for {
m.Lock()
ball.hits++
fmt.Println(name, ball.hits)
time.Sleep(100 * time.Millisecond)
m.Unlock()
}
}
2条答案
按热度按时间jecbmhm31#
在Go语言中,通道是非常棒的,你可以使用它们在goroutines之间进行通信。但是,为了方便起见,您可能希望在某些情况下使用
sync.Mutex
。这些情况如下:这里有三个examples and explanations
1.简单计数器
1.乒乓球比赛
1.最简单的缓存
1sbrub3j2#
一些示例信道用例:
*限制并发任务数(例如运行goroutine的数量)使用缓冲的通道容量(和/或长度)
*转移一个对象的所有权(一个且只有一个goroutine写它,而没有其他goroutine阅读它)
*协调、同步、发送信号、数据。
一些示例基元用例:
*保护结构体的内部状态(例如
sync.Mutex
或sync.RWMutex
)*性能关键(依赖于算法和用例,不是一般规则)
示例
为了让它更清楚,假设我们需要一个一秒计数器,所以在下面的例子中,我们计数一秒,然后打印计数器值,看看它计数的速度有多快:
注意:go版本go1.13.5 Linux/amd 64
代码:
1 -使用
sync.RWMutex
进行增量:2 -使用通道进行增量:
3 -使用定时器的通道:
4 -使用
time.AfterFunc
和通道同步: