In this article, we will explore the CompareAndSwapUintptr() Function in sync/atomic package in Go in details, along with examples.
Introduction:
Concurrency is a core feature of the Go programming language, which primarily uses goroutines and channels to achieve it. In some situations, low-level atomic operations are required for efficient concurrent code. The sync/atomic package in Go offers a set of functions for atomic memory access, including CompareAndSwapUintptr. In this article, we will discuss the CompareAndSwapUintptr function, its use cases, and provide a practical example.
What is CompareAndSwapUintptr Function ?
The CompareAndSwapUintptr function is part of the sync/atomic package in Go. It performs an atomic compare-and-swap operation on a uintptr value. The function prototype is as follows:
Syntax:
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
- addr: A pointer to the memory address storing the uintptr value that needs to be compared and potentially swapped.
- old: The uintptr value that is expected to be stored at the memory address.
- new: The uintptr value that will replace the old value if the comparison is successful.
- Return value: swapped- A boolean value that indicates whether the swap was successful (true) or not (false).
The CompareAndSwapUintptr function performs an atomic operation, ensuring that the comparison and swap occur without being interrupted by other goroutines. This is essential when working with shared memory in concurrent code.
Example
Let’s consider a simple example to demonstrate the use of the CompareAndSwapUintptr function. Suppose we have a shared uintptr value that multiple goroutines modify concurrently.
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var sharedValue uintptr
var wg sync.WaitGroup
update := func(id int) {
defer wg.Done()
for i := 0; i < 10; i++ {
for {
old := atomic.LoadUintptr(&sharedValue)
new := old + uintptr(id)
if atomic.CompareAndSwapUintptr(&sharedValue, old, new) {
break
}
}
}
}
wg.Add(5)
for i := 1; i <= 5; i++ {
go update(i)
}
wg.Wait()
fmt.Println("Final shared value:", sharedValue)
}
In this example, we have a uintptr sharedValue variable that we want to modify atomically. We use the CompareAndSwapUintptr function to ensure that the sharedValue is updated safely by multiple goroutines. Each goroutine attempts to add its ID to the sharedValue ten times. With five goroutines running concurrently, the expected final value of the sharedValue is the sum of the first five natural numbers multiplied by ten (i.e., (1 + 2 + 3 + 4 + 5) * 10 = 150).
Conclusion
The CompareAndSwapUintptr function in Go’s sync/atomic package provides a low-level atomic operation for safe access and modification of shared memory in concurrent code. When working with shared memory in concurrent programming, it is essential to use atomic operations to avoid data races and ensure data consistency. This article has provided a detailed explanation of the CompareAndSwapUintptr function and demonstrated its usage through an example.
To check more Go related articles. Pls click given below link:
https://techieindoor.com/category/leetcode/
https://pkg.go.dev/net/[email protected]