Middle+
Šta su atomarne operacije, koje vrste postoje i kada i kako ih je najbolje koristiti?
sobes.tech АИ
Одговор од АИ
Атомарне операције су операције над меморијом, чије извршавање је гарантовано да се завршава или потпуно, или уопште не почиње, и не могу бити прекинуте другим конкурирајућим операцијама. Оне су недељиве и безбедне за токове на хардверском нивоу.
У Go пакету sync/atomic пружа се скуп функција за извршавање атомарних операција:
| Функција | Опис |
|---|---|
AddInt32 |
Атомарно додаје вредност int32. |
AddInt64 |
Атомарно додаје вредност int64. |
AddUint32 |
Атомарно додаје вредност uint32. |
AddUint64 |
Атомарно додаје вредност uint64. |
AddUintptr |
Атомарно додаје вредност uintptr. |
CompareAndSwapInt32 |
Атомарно упоређује и мења (CAS) int32. |
CompareAndSwapInt64 |
Атомарно упоређује и мења (CAS) int64. |
CompareAndSwapUint32 |
Атомарно упоређује и мења (CAS) uint32. |
CompareAndSwapUint64 |
Атомарно упоређује и мења (CAS) uint64. |
CompareAndSwapUintptr |
Атомарно упоређује и мења (CAS) uintptr. |
CompareAndSwapPointer |
Атомарно упоређује и мења (CAS) unsafe.Pointer. |
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
}