在过去的几周里,我一直在与一个(不那么)简单的问题搏斗:
sync.Mutex
,相反,何时最好使用chan
?对于很多问题,似乎任何策略都可以与其他策略互换 - 而这只是问题所在!
在Golang文档中找到this video。下面,我冒昧地在操场上指示代码,并将其转换为sync.Mutex
等效代码。
注意:
chan
实现在同一时间内做了更多工作(达到12)* 操场:
使用chan
:
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
:
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()
}
}
答案 0 :(得分:3)
在某些情况下,频道最好,在某些sync.Mutex
中,对于这个简单示例sync.Mutex
比频道宽10倍<强> :
例如这里的差额是1.01亿(想象一下,你需要一秒计数器):
1-考虑这个简单的代码:
package main
import (
"sync"
"time"
)
func main() {
var i rwm
go func() {
for {
i.inc() // free running counter
}
}()
time.Sleep(1 * time.Second)
println(i.read()) // sampling the counter
}
type rwm struct {
sync.RWMutex
i int
}
func (l *rwm) inc() {
l.Lock()
defer l.Unlock()
l.i++
}
func (l *rwm) read() int {
l.RLock()
defer l.RUnlock()
return l.i
}
输出:
11227280
2-使用频道:
package main
import "time"
func main() {
ch := make(chan int)
go func() {
timeout := time.NewTimer(1 * time.Second)
defer timeout.Stop()
i := 1
for {
select {
case <-timeout.C:
ch <- i
return
default:
i++
}
}
}()
println(<-ch)
}
输出:
112362269
差:
112362269-11227280=101134989
112362269/11227280=10x