函数WithMutex
和WithoutMutex
会产生不同的结果。
WithoutMutex
, Waitgroup
实施也会失去价值。
可能出现什么问题?
P.S。我在Windows 10和Go 1.8.1上
package main
import (
"fmt"
"sync"
)
var p = fmt.Println
type MuType struct {
list []int
*sync.RWMutex
}
var muData *MuType
var data *NonMuType
type NonMuType struct {
list []int
}
func (data *MuType) add(i int, wg *sync.WaitGroup) {
data.Lock()
defer data.Unlock()
data.list = append(data.list, i)
wg.Done()
}
func (data *MuType) read() []int {
data.RLock()
defer data.RUnlock()
return data.list
}
func (nonmu *NonMuType) add(i int, wg *sync.WaitGroup) {
nonmu.list = append(nonmu.list, i)
wg.Done()
}
func (nonmu *NonMuType) read() []int {
return nonmu.list
}
func WithoutMutex() {
nonmu := &NonMuType{}
nonmu.list = make([]int, 0)
var wg = sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go nonmu.add(i, &wg)
}
wg.Wait()
data = nonmu
p(data.read())
}
func WithMutex() {
mtx := &sync.RWMutex{}
withMu := &MuType{list: make([]int, 0)}
withMu.RWMutex = mtx
var wg = sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go withMu.add(i, &wg)
}
wg.Wait()
muData = withMu
p(muData.read())
}
func stressTestWOMU(max int) {
p("Without Mutex")
for ii := 0; ii < max; ii++ {
WithoutMutex()
}
}
func stressTest(max int) {
p("With Mutex")
for ii := 0; ii < max; ii++ {
WithMutex()
}
}
func main() {
stressTestWOMU(20)
stressTest(20)
}
答案 0 :(得分:1)
对于并发写入来说,切片是不安全的,所以我并不感到惊讶WithoutMutex
看起来根本不一致,并且丢弃了项目。
WithMutex
版本始终有10个项目,但是订单混乱。这也是预料之中的,因为互斥锁可以保护它,因此一次只能添加一个互斥锁。虽然不知道哪个goroutine会按哪种顺序运行,但是看看哪个快速生成的goroutine会首先追加它是一场竞赛。
waitgroup不会执行任何操作来控制访问或强制执行排序。它只是在最后提供了一切信号。