Atomic operations are a type of operation that are executed as a single, uninterruptible sequence of instructions. In Go, the sync/atomic
package provides a set of atomic operations that can be used to safely access and modify shared data without the risk of concurrent access.
Here’s an example of using an atomic counter in Go:
package main
import (
"fmt"
"sync/atomic"
"time"
)
func main() {
var counter int64
for i := 0; i < 50; i++ {
go func() {
for {
atomic.AddInt64(&counter, 1)
time.Sleep(time.Millisecond)
}
}()
}
time.Sleep(time.Second)
fmt.Println("counter:", atomic.LoadInt64(&counter))
}
In this example, a variable counter
of type int64
is declared and will be used as an atomic counter. A loop creates 50 Goroutines that continuously increment the counter using the atomic.AddInt64
function. The atomic.LoadInt64
a function is used to safely access the value of the counter. The example demonstrates the use of atomic operations to safely access and modify shared data from multiple Goroutines, even though the Goroutines are running concurrently.
Here’s another example of using an atomic counter to maintain a tally of values as they’re added by multiple Goroutines:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var wg sync.WaitGroup
var counter int64
for i := 0; i < 100; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
atomic.AddInt64(&counter, 1)
fmt.Println("Goroutine", id, "incremented counter to", atomic.LoadInt64(&counter))
}(i)
}
wg.Wait()
fmt.Println("Final Counter Value:", counter)
}
In this example, a sync.WaitGroup
is used to wait for all Goroutines to complete before printing the final value of the counter. Each Goroutine increments the counter using the atomic.AddInt64
function and then prints its current value using the atomic.LoadInt64
function. The use of atomic operations ensures that the counter is updated and accessed safely, even though multiple Goroutines are executing concurrently.
Leave a Reply