繁体   English   中英

GOMAXPROCS = 1时的数据竞争

[英]Data race when GOMAXPROCS=1

我正在尝试理解Golang 典型数据竞赛之一 ,从多个goroutine访问未受保护的全局变量可能会导致竞争条件:

var service map[string]net.Addr

func RegisterService(name string, addr net.Addr) {
  service[name] = addr
}

func LookupService(name string) net.Addr {
  return service[name]
}

接下来我们可以通过使用互斥锁来保护它来解决这个问题:

var (
  service   map[string]net.Addr
  serviceMu sync.Mutex
)

func RegisterService(name string, addr net.Addr) {
  serviceMu.Lock()
  defer serviceMu.Unlock()
  service[name] = addr
}

func LookupService(name string) net.Addr {
  serviceMu.Lock()
  defer serviceMu.Unlock()
  return service[name]
}

到现在为止还挺好。 令我困惑的是这个:

这个问题的接受答案表明,一个CPU绑定的goroutine会将多路复用到同一个OS线程上的其他goroutine(除非我们用runtime.Gosched()明确地产生)。 这是有道理的。

对我来说,上面的RegisterService()LookupService()函数看起来是CPU绑定的,因为没有IO和没有yield。 这个对吗?

如果是,如果GOMAXPROCS设置为1 ,那么上面例子中的互斥是否仍然是绝对必要的? 在竞争条件可能发生的时候,goroutines是否受CPU约束这一事实不会照顾它吗?

即使它确实如此,我也认为在现实生活中使用互斥锁仍然是一个好主意,因为我们可能无法保证GOMAXPROCS的设置。 还有其他原因吗?

正如FUZxxl和Nick Craig-Wood所指出的,goroutines的当前行为是特定于实现的。 所以,也许,读取或写入地图可以产生。 考虑到映射不是线程安全的 ,正确的并发访问需要互斥或其他同步。

作为互斥锁的替代方案,您可以生成一个goroutine,它可以在地图上执行所有操作并通过通道与它通信:

type writereq struct {
    key string
    value net.Addr
    reply chan struct{}
}

type readreq struct {
    key string
    reply chan net.Addr
}

var service map[string]net.Addr
var reads = make(chan readreq)
var writes = make(chan writereq)

func RegisterService(name string, addr net.Addr) {
    w := writereq{name, addr, make(chan struct{})}
    writes <- w
    return <-w.reply // return after registration confirmation
}

func LookupService(name string) net.Addr {
    r := readreq{name, make(chan net.Addr)}
    reads <- r
    return <-r.reply
}

func serveRegistry() {
    for {
        select {
        case r := <-reads:
            r.reply <- service[r.name]
        case w := <-writes:
            service[w.name] = w.addr
            w.reply <- struct{}
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM