簡體   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