In Go language, atomic packages supply lower level atomic memory that is helpful is implementing synchronization algorithms. The LoadPointer() function in Go language is used to atomically load *addr. This function is defined under the atomic package. Here, you need to import “sync/atomic” and “unsafe” package in order to use these functions.
Syntax:
func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
Here, addr indicates address.
Note: (*unsafe.Pointer) is the pointer to a unsafe.Pointer value. And unsafe.Pointer type is helpful in enabling transitions between arbitrary types and builtin uintptr type. Moreover, unsafe is a package that is helpful in type safety of Go programs.
Return Value: It automically loads *addr and returns unsafe.Pointer.
Example 1:
// Program to illustrate the usage of // LoadPointer function in Golang // Including main package package main // importing fmt, // sync/atomic and unsafe import ( "fmt" "sync/atomic" "unsafe" ) // Defining a struct type L type L struct { x, y, z int } // Declaring pointer // to L struct type var PL *L // Calling main func main() { // Defining *addr unsafe.Pointer var unsafepL = (*unsafe.Pointer)(unsafe.Pointer(&PL)) // Defining value // of unsafe.Pointer var px L // Calling StorePointer and // storing unsafe.Pointer // value to *addr atomic.StorePointer( unsafepL, unsafe.Pointer(&px)) // Calling LoadPointer() method px1 := (*L)(atomic.LoadPointer(unsafepL)) // Returns true if *addr is // loaded else returns false fmt.Println(px1 == &px) // Prints unsafe.Pointer fmt.Println(&px1) } |
Output:
true 0xc0000b8018 // Can be different at different run times
Here, the StorePointer method adds value to the *addr and then LoadPointer method atomically loads *addr. So, here loading is accomplished hence, true is returned and the value of unsafe.Pointer returned here can be different at different run times.
Example 2:
// Program to illustrate the usage of // LoadPointer function in Golang // Including main package package main // importing fmt, // sync/atomic and unsafe import ( "fmt" "sync/atomic" "unsafe" ) // Defining a struct type L type L struct { x, y, z int } // Declaring pointer // to L struct type var PL *L // Calling main func main() { // Defining *addr unsafe.Pointer var unsafepL = (*unsafe.Pointer)(unsafe.Pointer(&PL)) // Defining value // of unsafe.Pointer var px L // Calling LoadPointer() method px1 := (*L)(atomic.LoadPointer(unsafepL)) // Returns true if *addr is // loaded else returns false fmt.Println(px1 == &px) // Prints unsafe.Pointer fmt.Println(&px1) } |
Output:
false 0xc00000e028 // A random value is returned in each run
Here, false is returned as here the unsafe.pointer is not stored before so, LoadPointer() method was not able to load the *addr. Moreover, the address value returned here is the address of px1.