Atomic Operations
Atomik amallar
Oddiy sonni oshirish (counter++) uchun sync.Mutex ishlatish — bu ancha "og'ir qurol": Lock/Unlock chaqirish ma'lum vaqt talab qiladi. Faqat bitta sonni xavfsiz oshirish kerak bo'lgan sodda holatlar uchun Go yengilroq vosita taklif qiladi: sync/atomic paketi.
"Atomik" so'zi — "bo'linmaydigan" degani: atomik amal boshqa hech qanday goroutine "o'rtasiga kirib ololmaydigan" bitta, yaxlit qadam sifatida bajariladi. Bu — kalitni olib-qo'yish (Mutex) o'rniga, protsessorning o'zi kafolatlaydigan "bir zumlik" amal.
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int64
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
atomic.AddInt64(&counter, 1)
}()
}
wg.Wait()
fmt.Println(atomic.LoadInt64(&counter))
}atomic.AddInt64(&counter, 1) — counter++ning xavfsiz varianti: u "eskisini o'qi, birni qo'sh, yangisini yoz" jarayonini bitta bo'linmas amal qilib bajaradi, hech qanday Mutex kerak emas. atomic.LoadInt64(&counter) esa qiymatni xavfsiz o'qish uchun ishlatiladi — oddiy counterni to'g'ridan-to'g'ri o'qish, boshqa goroutine hali yozayotgan bo'lsa, texnik jihatdan noaniq natija berishi mumkin.
Qachon atomic, qachon Mutex ishlatish kerak? Agar himoyalanadigan narsa bitta oddiy son (counter, bayroq) bo'lsa — atomic yengil va tez. Agar bir nechta qiymatni birgalikda, izchil holda o'zgartirish kerak bo'lsa (masalan, Stack'ning items slice'i — uzunligi ham, mazmuni ham birgalikda) — Mutex kerak, chunki atomic faqat bitta son ustida ishlaydi.
>_ Exercise
Atomik hisoblagich bilan muvaffaqiyat/xato sonini sanang.
- •successCount va failCount uchun ikkita int64 o'zgaruvchi yarating
- •100 ta goroutine ichida: juft raqamlar uchun successCount'ni, toq raqamlar uchun failCount'ni atomic.AddInt64 bilan oshiring
- •ikkalasini ham atomic.LoadInt64 bilan o'qib chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
sync/atomic — bitta sonni Mutex'siz, yengil va tez tarzda xavfsiz o'zgartirish uchun ishlatiladi; bir nechta qiymatni birgalikda o'zgartirish kerak bo'lganda esa Mutex kerak bo'ladi.
$ go run main.go
Kodingizni ishga tushiring