Sobes.tech
Middle+

Атомдук операциялар деген эмне, алардын түрлөрү кандай жана качан жана кантип жакшыраак колдонуу керек?

sobes.tech AI

AIден жооп

Атомардык операциялар — бул эс тутумдагы операциялар, алардын аткарылышы толугу менен аяктап же эч качан башталбайт деп кепилдик берилет жана алар башка атаандаш операциялар менен үзүлө албайт. Алар аппараттык деңгээлде бөлүнбөйт жана потокко коопсуз.

Go пакеттеги sync/atomic атомардык операцияларды аткаруу үчүн функциялар топтомун сунуштайт:

Функция Түшүндүрмө
AddInt32 int32 мааниге атомардык кошуу.
AddInt64 int64 мааниге атомардык кошуу.
AddUint32 uint32 мааниге атомардык кошуу.
AddUint64 uint64 мааниге атомардык кошуу.
AddUintptr uintptr мааниге атомардык кошуу.
CompareAndSwapInt32 int32 үчүн салыштырып, алмаштыруу (CAS).
CompareAndSwapInt64 int64 үчүн салыштырып, алмаштыруу (CAS).
CompareAndSwapUint32 uint32 үчүн салыштырып, алмаштыруу (CAS).
CompareAndSwapUint64 uint64 үчүн салыштырып, алмаштыруу (CAS).
CompareAndSwapUintptr uintptr үчүн салыштырып, алмаштыруу (CAS).
CompareAndSwapPointer unsafe.Pointer үчүн салыштырып, алмаштыруу (CAS).
LoadInt32 int32 маанини атомардык жүктөө.
LoadInt64 int64 маанини атомардык жүктөө.
LoadUint32 uint32 маанини атомардык жүктөө.
LoadUint64 uint64 маанини атомардык жүктөө.
LoadUintptr uintptr маанини атомардык жүктөө.
LoadPointer unsafe.Pointer маанини атомардык жүктөө.
StoreInt32 int32 маанини атомардык сактоо.
StoreInt64 int64 маанини атомардык сактоо.
StoreUint32 uint32 маанини атомардык сактоо.
StoreUint64 uint64 маанини атомардык сактоо.
StoreUintptr uintptr маанини атомардык сактоо.
StorePointer unsafe.Pointer маанини атомардык сактоо.
SwapInt32 int32 маанилерин атомардык алмаштыруу.
SwapInt64 int64 маанилерин атомардык алмаштыруу.
SwapUint32 uint32 маанилерин атомардык алмаштыруу.
SwapUint64 uint64 маанилерин атомардык алмаштыруу.
SwapUintptr uintptr маанилерин атомардык алмаштыруу.
SwapPointer unsafe.Pointer маанилерин атомардык алмаштыруу.

Атомардык операцияларды колдонуу эң жакшы болот, эгер жөнөкөй, төмөн деңгээлдеги синхрондоштуруу керек болсо, көбүнчө эсептегичтер же флагдар үчүн, мьютекссиз. Алар минималдуу чыгымдар менен жакшы иштешет.

Атомардык эсептегичтин мисалы:

package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	var counter int64
	var wg sync.WaitGroup

	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			// Атомардык эсептегичти көбөйтүү
			atomic.AddInt64(&counter, 1)
			wg.Done()
		}()
	}

	wg.Wait()
	// Атомардык түрдө эсептегичтин маанисин алуу
	fmt.Println("Final Counter:", atomic.LoadInt64(&counter))
}

CompareAndSwap колдонуу мисалы:

package main

import (
	"fmt"
	"sync/atomic"
)

func main() {
	var value int32 = 10

	// Эгер учурдагы мааниси 10 болсо, алмаштыруу 20га
	swapped := atomic.CompareAndSwapInt32(&value, 10, 20)
	fmt.Println("Swapped:", swapped) // Swapped: true
	fmt.Println("Value:", value)   // Value: 20

	// Эгер учурдагы мааниси 10 болсо, алмаштыруу 30га
	swapped = atomic.CompareAndSwapInt32(&value, 10, 30)
	fmt.Println("Swapped:", swapped) // Swapped: false
	fmt.Println("Value:", value)   // Value: 20
}