Introduction to sync.Atomic
For atomic operations on variables in golang, the sync/atomic package offers certain low-level methods. In Go, these methods allow multiple goroutines to safely modify shared variables without using locks or other explicit synchronization. Functions like AddInt64
, AddUint32
, CompareAndSwapInt32
, etc. used to perform basic arithmetic on different types of variables can be found in the atom
package. The AddInt64
method for example, guarantees that modifications made by other goroutines will be seen when adding a certain value to an int64
variable in atomic style.
Why should we use sync.atomic
?
We can use sync.Atomic technically just like we use sync.Mutex
with its locking mechanism. But here to make it easier to lock a variable we can also use sync.Atomic which is an easier command.
Method Usage
Some methods that we can use to implement sync.Atomic:
AddInt64
is used to do locking forprimitive
typeint64
variablesAddUint32
is used to lock theprimitive
variable typeuint32
- and much more we can just visit the link https://pkg.go.dev/sync/atomic
sync.atomic
implementation and samples
Functions like LoadInt32
, StoreInt64
, LoadPointer
load and store data from and to variables atomically
. Securely access variables shared by multiple goroutines with these handy utilities. Atomic packages allow safe alteration of shared variables, as shown here:
func main() {
var wg = &sync.WaitGroup{}
var counter int64 = 0
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
for j := 0; j < 100; j++ {
atomic.AddInt64(&counter, 1)
}
wg.Done()
}()
}
wg.Wait()
fmt.Println("result", atomic.LoadInt64(&counter))
}
We can see that when we set the counter
variable we use atomic.AddInt64(&counter, 1)
. This is so that we can use the locking mechanism and there is no race condition
when we set the variable at the same time. Then when we want to retrieve data from the counter
variable, we use atomic.LoadInt64(&counter)
to get the last variable data and there is no value left in the variable.
Conclusion
This sync/atomic is just like the locking mechanism we learned earlier in
Getting to know Sync Mutex. But this is an option for us if we want to further explore locking. But note that sync/atomic only applies to primitive
variables as they are supported by the library.