Ce face sync/atomic.Bool
atomic.Bool ține un bool care poate fi citit și scris din mai multe goroutine fără cursă de date. Valoarea zero este false. Load citește, Store scrie, Swap scrie și returnează valoarea veche, iar CompareAndSwap(false, true) schimbă valoarea doar dacă era false.
CompareAndSwap(false, true) este un mod simplu de a face „doar primul trece”: exact un goroutine primește true.
Ce returnează
Load: valoarea. Swap: valoarea veche. CompareAndSwap: dacă a schimbat. Store: nimic.
Exemple
Exemplul 1: Serviciu închis o singură dată
package main
import (
"fmt"
"sync"
"sync/atomic"
)
type Serviciu struct {
inchis atomic.Bool
}
func (s *Serviciu) Inchide() bool {
return s.inchis.CompareAndSwap(false, true)
}
func main() {
s := &Serviciu{}
var inchideriReale atomic.Int32
var wg sync.WaitGroup
for range 10 {
wg.Go(func() {
if s.Inchide() {
inchideriReale.Add(1)
}
})
}
wg.Wait()
fmt.Println("Închis:", s.inchis.Load())
fmt.Println("Închideri efectuate:", inchideriReale.Load())
}
Rezultat
Închis: true
Închideri efectuate: 1
Exemplul 2: Store, Load și Swap
package main
import (
"fmt"
"sync/atomic"
)
func main() {
var mentenanta atomic.Bool
fmt.Println("Valoare inițială:", mentenanta.Load())
mentenanta.Store(true)
fmt.Println("După Store(true):", mentenanta.Load())
vechi := mentenanta.Swap(false)
fmt.Println("Swap(false) a returnat:", vechi, "- acum:", mentenanta.Load())
}
Rezultat
Valoare inițială: false
După Store(true): true
Swap(false) a returnat: true - acum: false
Greșeli frecvente
- Folosești un
boolobișnuit ca semnal de oprire între goroutine (for !stop {}). Fără sincronizare, compilatorul poate presupune că valoarea nu se schimbă și bucla nu se mai oprește; foloseșteatomic.Bool, un canal saucontext.
Comenzi înrudite
sync/atomic.Int32: Un int32 cu operații atomice (Add, Load, Store, Swap, CompareAndSwap); la fel ca atomic.Int64, dar pe 32 de biți.sync.Once: Garantează că o funcție rulează o singură dată, chiar dacă Do este apelat de multe goroutine (inițializare leneșă).context.WithCancel: Creează un context copil și o funcție cancel; apelul cancel() anunță toate goroutine-urile care îl folosesc să se oprească.