我想了解Golang typical data races之一,訪問來自多個夠程不受保護的全局變量可能導致競爭條件:數據競爭時GOMAXPROCS = 1
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]
}
到目前爲止,這麼好。什麼是困惑我的是:
接受的答案,以this question表明,一個CPU綁定的goroutine將任何餓死已複用到相同的操作系統線程(除非我們明確地runtime.Gosched()
收益率)等夠程。這是有道理的。
對我來說,上面的RegisterService()
和LookupService()
函數看起來是CPU綁定的,因爲沒有IO和沒有良率。它是否正確?
如果是,並且GOMAXPROCS設置爲1,那麼在上面的示例中,互斥體仍然是嚴格必要的嗎?在競爭條件可能發生的地點,goroutines是否受到CPU限制的事實不是照顧它的事實嗎?
即使這樣做,我認爲在現實生活中使用互斥鎖在這裏仍然是一個好主意,因爲我們可能無法保證GOMAXPROCS被設置爲什麼。還有其他原因嗎?
的圍棋程序是CPU密集型並不意味着存在的事實沒有機會在兩者之間進行調度。互斥體仍然是必需的。 – fuz
謝謝。因此,一個CPU綁定的goroutine可能會在同一個OS線程上餓死其他goroutine,或者它可能不會。無論如何我們無法保證。如果是這樣,你是否知道什麼因素決定了一家公寓是否餓死別人? –
CPU綁定的goroutine用於在同一線程上捱餓,但Go 1.2(幾乎已發佈)擁有先發制人的調度器,因此不再是這種情況。這只是一個實施細節恕我直言。 (在go 1.2中,每個函數調用都是搶佔的機會,所以如果你的CPU綁定函數沒有調用其他函數,它會在同一個線程上餓死其他函數)。 –