π¬ Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ data race (Π³ΠΎΠ½ΠΊΠ° Π΄Π°Π½Π½ΡΡ
) Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ Go?
πΠΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ β ΠΎΠ΄Π½ΠΈ ΠΈΠ· Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½Π΅Π½Π½ΡΡ ΠΈ ΡΠ°ΠΌΡΡ ΡΠ»ΠΎΠΆΠ½ΡΡ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΡΠΈΠΏΠΎΠ² ΠΎΡΠΈΠ±ΠΎΠΊ Π² ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌΠ°Ρ . ΠΠΎΠ½ΠΊΠ° Π΄Π°Π½Π½ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π΄Π²Π΅ Π³ΠΎΡΡΡΠΈΠ½Ρ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ ΠΊ ΠΎΠ΄Π½ΠΎΠΉ ΠΈ ΡΠΎΠΉ ΠΆΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ, ΠΈ Ρ ΠΎΡΡ Π±Ρ ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΉ β Π·Π°ΠΏΠΈΡΡ. Π§ΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, Π² Go ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ.
πRace Condition (ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π³ΠΎΠ½ΠΊΠΈ) β Π±ΠΎΠ»Π΅Π΅ ΡΠΈΡΠΎΠΊΠΎΠ΅ ΠΏΠΎΠ½ΡΡΠΈΠ΅, ΡΠ΅ΠΌ Π³ΠΎΠ½ΠΊΠ° Π΄Π°Π½Π½ΡΡ . ΠΠ½ΠΎ ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ ΡΠΈΡΡΠ°ΡΠΈΡ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ΄ΠΊΠ° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ. ΠΠΎΠ½ΠΊΠ° Π΄Π°Π½Π½ΡΡ β ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π²ΠΈΠ΄ΠΎΠ² ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ Π³ΠΎΠ½ΠΊΠΈ, Π½ΠΎ Π½Π΅ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΉ.
ΠΡΠΈΠΌΠ΅Ρ Π³ΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ , ΠΊΠΎΡΠΎΡΠ°Ρ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ²Π΅ΡΡΠΈ ΠΊ ΡΠ±ΠΎΡΠΌ ΠΈ ΠΏΠΎΠ²ΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ:
πΠΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ β ΠΎΠ΄Π½ΠΈ ΠΈΠ· Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½Π΅Π½Π½ΡΡ ΠΈ ΡΠ°ΠΌΡΡ ΡΠ»ΠΎΠΆΠ½ΡΡ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΡΠΈΠΏΠΎΠ² ΠΎΡΠΈΠ±ΠΎΠΊ Π² ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΡΡ ΡΠΈΡΡΠ΅ΠΌΠ°Ρ . ΠΠΎΠ½ΠΊΠ° Π΄Π°Π½Π½ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π΄Π²Π΅ Π³ΠΎΡΡΡΠΈΠ½Ρ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ ΠΊ ΠΎΠ΄Π½ΠΎΠΉ ΠΈ ΡΠΎΠΉ ΠΆΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ, ΠΈ Ρ ΠΎΡΡ Π±Ρ ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΉ β Π·Π°ΠΏΠΈΡΡ. Π§ΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, Π² Go ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ.
πRace Condition (ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π³ΠΎΠ½ΠΊΠΈ) β Π±ΠΎΠ»Π΅Π΅ ΡΠΈΡΠΎΠΊΠΎΠ΅ ΠΏΠΎΠ½ΡΡΠΈΠ΅, ΡΠ΅ΠΌ Π³ΠΎΠ½ΠΊΠ° Π΄Π°Π½Π½ΡΡ . ΠΠ½ΠΎ ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ ΡΠΈΡΡΠ°ΡΠΈΡ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ΄ΠΊΠ° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ. ΠΠΎΠ½ΠΊΠ° Π΄Π°Π½Π½ΡΡ β ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π²ΠΈΠ΄ΠΎΠ² ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ Π³ΠΎΠ½ΠΊΠΈ, Π½ΠΎ Π½Π΅ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΉ.
ΠΡΠΈΠΌΠ΅Ρ Π³ΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½ΡΡ , ΠΊΠΎΡΠΎΡΠ°Ρ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ²Π΅ΡΡΠΈ ΠΊ ΡΠ±ΠΎΡΠΌ ΠΈ ΠΏΠΎΠ²ΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ:
func main() {
c := make(chan bool)
m := make(map[string]string)
go func() {
m["1"] = "a" //
ΠΠ΅ΡΠ²ΡΠΉ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΠΉ Π΄ΠΎΡΡΡΠΏ
c <- true
}()
m["2"] = "b" //
ΠΡΠΎΡΠΎΠΉ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠ½ΡΠΉ Π΄ΠΎΡΡΡΠΏ <-c
for k, v := range m {
fmt.Println(k, v)
}
}
βοΈΠ§ΡΠΎΠ±Ρ ΠΏΠΎΠΌΠΎΡΡ Π΄ΠΈΠ°Π³Π½ΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°ΠΊΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ, Go Π²ΠΊΠ»ΡΡΠ°Π΅Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ Π΄Π΅ΡΠ΅ΠΊΡΠΎΡ Π³ΠΎΠ½ΠΎΠΊ Π΄Π°Π½Π½ΡΡ
. ΠΠ»Ρ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΡΠ»Π°Π³ -race
Π² ΠΊΠΎΠΌΠ°Π½Π΄Ρ go:
$ go test -race mypkg
$ go run -race mysrc.go
$ go build -race mycmd
$ go install -race mypkg
πΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ GORACE
ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π΄Π΅ΡΠ΅ΠΊΡΠΎΡΠ° Π³ΠΎΠ½ΠΎΠΊ Π΄Π°Π½Π½ΡΡ
, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ:
$ GORACE="log_path=/tmp/race/report Strip_path_prefix=/my/go/sources/" go test -race
π ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅