π¬ Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ Π°ΡΠΎΠΌΠ°ΡΠ½Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ ΠΈ Π΄Π»Ρ ΡΠ΅Π³ΠΎ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ ΠΏΠ°ΠΊΠ΅Ρ atomic?
ΠΡΠΎΠΌΠ°ΡΠ½Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π·Π° ΠΎΠ΄ΠΈΠ½ ΡΠ°Π³ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π΄ΡΡΠ³ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΈΠ»ΠΈ, Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ Go, Π΄ΡΡΠ³ΠΈΡ Π³ΠΎΡΡΡΠΈΠ½. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π½Π΅Π»ΡΠ·Ρ ΠΏΡΠ΅ΡΠ²Π°ΡΡ Π² ΡΠ΅ΡΠ΅Π΄ΠΈΠ½Π΅ Π΅Π΅ ΡΠ°Π±ΠΎΡΡ.
Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Go ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΏΠ°ΠΊΠ΅Ρ
ΠΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π½ΠΈΠΆΠ΅, ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ Π²ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΠ΅ race condition Π²ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΡΠ΅Π½ΠΈΡ ΠΈ Π·Π°ΠΏΠΈΡΠΈ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ Π΄ΠΎΠ»ΠΆΠ½Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈΜ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΡΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠΌ
ΠΡΠΎ ΡΡΡΡΠΊΡΡΡΠ° Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΡΡΠ΅Π±ΡΠ΅ΠΌΠΎΠΈΜ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ
ΠΡΠΎ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ΅ΠΊΡΡΠ΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ
ΠΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π³ΠΎΡΡΡΠΈΠ½, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ ΠΎΠ±ΡΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ. ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΠΊΠ΅ΡΠ°
Π€ΡΠ½ΠΊΡΠΈΡ
ΠΡΠΎΠΌΠ°ΡΠ½Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π·Π° ΠΎΠ΄ΠΈΠ½ ΡΠ°Π³ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π΄ΡΡΠ³ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΈΠ»ΠΈ, Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ Go, Π΄ΡΡΠ³ΠΈΡ Π³ΠΎΡΡΡΠΈΠ½. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π½Π΅Π»ΡΠ·Ρ ΠΏΡΠ΅ΡΠ²Π°ΡΡ Π² ΡΠ΅ΡΠ΅Π΄ΠΈΠ½Π΅ Π΅Π΅ ΡΠ°Π±ΠΎΡΡ.
Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Go ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΏΠ°ΠΊΠ΅Ρ
atomic
, ΠΊΠΎΡΠΎΡΡΠΈΜ Π² Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
ΠΏΡΠΎΡΡΡΡ
ΡΠ»ΡΡΠ°ΡΡ
ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠΌΠΎΡΡ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΌΡΡΡΠ΅ΠΊΡΠ°. Π‘ ΠΏΠΎΠΌΠΎΡΡΡ Π½Π΅Π³ΠΎ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π΄ΠΎΡΡΡΠΏ ΠΊ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΠΌ ΡΡΠ΅ΡΡΠΈΠΊΠ°ΠΌ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ
Π³ΠΎΡΡΡΠΈΠ½, Π½Π΅ ΠΈΠΌΠ΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠ΅ΠΈΜ ΠΈ Π½Π΅ Π±Π΅ΡΠΏΠΎΠΊΠΎΡΡΡ ΠΎ race condition. ΠΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π½ΠΈΠΆΠ΅, ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ Π²ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΠ΅ race condition Π²ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΡΠ΅Π½ΠΈΡ ΠΈ Π·Π°ΠΏΠΈΡΠΈ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ Π΄ΠΎΠ»ΠΆΠ½Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈΜ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΡΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠΌ
atomic
.package main
import (
"fmt"
"sync"
"sync/atomic"
)
type atomCounter struct {
val int64 }
ΠΡΠΎ ΡΡΡΡΠΊΡΡΡΠ° Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΡΡΠ΅Π±ΡΠ΅ΠΌΠΎΠΈΜ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ
int64
.func (c *atomCounter) Value() int64 {
return atomic.LoadInt64(&c.val)
}
ΠΡΠΎ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ΅ΠΊΡΡΠ΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ
int64
, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ atomic.LoadInt64()
.func main() {
X := 100
Y := 4
var waitGroup sync.WaitGroup
counter := atomCounter{}
for i := 0; i < X; i++ {
ΠΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π³ΠΎΡΡΡΠΈΠ½, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ ΠΎΠ±ΡΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ. ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΠΊΠ΅ΡΠ°
atomic
Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΠΎΠ±ΡΠ΅ΠΈΜ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΈΜ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΏΡΠΎΡΡΠΎΠΈΜ ΡΠΏΠΎΡΠΎΠ± ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ race condition ΠΏΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ.waitGroup.Add(1)
go func(no int) {
defer waitGroup.Done()
for i := 0; i < Y; i++ {
atomic.AddInt64(&counter.val, 1)
}
Π€ΡΠ½ΠΊΡΠΈΡ
atomic.AddInt64()
Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Ρ val ΡΡΡΡΠΊΡΡΡΡ counter
.}(i)
}
waitGroup.Wait()
fmt.Println(counter.Value())
}