2 回答
TA贡献1802条经验 获得超6个赞
你的问题的答案是肯定的,正如沃尔克所说。
我会给你一个更惯用的 Go 解决方案:
every resources of goroutines in S take a sync.RWMutex
the goroutines in S read after sync.RWMutex.Rlock()
the goroutines in S write after sync.RWMutex.Lock()
extra goroutine R read after sync.RWMutex.Rlock()
我认为你只是进入了错误的区域,这应该是一个简单的问题。:)
如果我误解了你,请告诉我。
TA贡献1864条经验 获得超2个赞
由于所有的困惑而回答自己。
sync.RWMutex是的,如果写入不会相互竞争,则使用 的读锁进行写入并使用其写入锁进行读取是安全的。
例子:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
m := &sync.RWMutex{}
wg := &sync.WaitGroup{}
maxWriters := 5
wg.Add(maxWriters+1)
allData := make([]uint64, maxWriters)
go showAccumulatedData(m, wg, allData)
for i := 0; i < maxWriters; i++ {
go writeData(m, wg, &allData[i])
}
wg.Wait()
fmt.Println(accumulateData(m, allData))
}
func writeData(m *sync.RWMutex, wg *sync.WaitGroup, d *uint64) {
for i := 0; i < 1000; i++ {
m.RLock()
*d++ // Write during read-lock.
m.RUnlock()
time.Sleep(time.Millisecond)
}
wg.Done()
}
func showAccumulatedData(m *sync.RWMutex, wg *sync.WaitGroup, allData []uint64) {
for i := 0; i < 15; i++ {
fmt.Println(accumulateData(m, allData))
time.Sleep(time.Millisecond*50)
}
wg.Done()
}
func accumulateData(m *sync.RWMutex, allData []uint64) uint64 {
var accumulator uint64
m.Lock()
for _, v := range allData {
accumulator += v // Read during write-lock.
}
m.Unlock()
return accumulator
}
- 2 回答
- 0 关注
- 106 浏览
添加回答
举报