Из the Dave Cheney Blog, следующий код, по-видимому, вызывает случай гонки, которые могут быть решены только путем изменения func (RPC) version() int
к func (*RPC) version() int
:Почему метод структуры, который не читает/не записывает его содержимое, все еще вызывает расу?
package main
import (
"fmt"
"time"
)
type RPC struct {
result int
done chan struct{}
}
func (rpc *RPC) compute() {
time.Sleep(time.Second) // strenuous computation intensifies
rpc.result = 42
close(rpc.done)
}
func (RPC) version() int {
return 1 // never going to need to change this
}
func main() {
rpc := &RPC{done: make(chan struct{})}
go rpc.compute() // kick off computation in the background
version := rpc.version() // grab some other information while we're waiting
<-rpc.done // wait for computation to finish
result := rpc.result
fmt.Printf("RPC computation complete, result: %d, version: %d\n", result, version)
}
После просмотра кода несколько раз, у меня было трудное время, полагая, что код был случай гонки. Тем не менее, при работе с -race, он утверждает, что была запись в rpc.result=42
, а предыдущая - version := rpc.version()
. Я понимаю, пишут, поскольку goroutine меняет значение rpc.result
, но как насчет чтения? Где в методе version()
происходит чтение? Это не касается какого-либо из значений RPC, только возвращение 1.
Я хотел бы понять следующее:
1) Почему это конкретная строка считается прочитанной на УИП структуру?
2) Почему смена RPC
на *RPC
решит проблему?
Это проясняет все, спасибо – AJPennster