当前位置:网站首页>Day 7 of "learning to go concurrent programming in 7 days" go language concurrent programming atomic atomic actual operation includes ABA problem
Day 7 of "learning to go concurrent programming in 7 days" go language concurrent programming atomic atomic actual operation includes ABA problem
2022-06-27 22:26:00 【Sledgehammer love programming】
Why is it explained in the last article Atmoic operation , Because atomic Operations are rarely used in business development , So put it at the end . But in terms of importance ,atomic Operation is the core and key link .
List of articles
Catalog
One 、Atomic- Introduction to atomic operation
Two 、go Language Atomic Source code analysis and actual operation
2.1 Atomic Key functions and their definitions
2.3 Atomic operations on arbitrary data structures
One 、Atomic- Introduction to atomic operation
Atomic operation has nothing to do with atoms , It mainly borrows the concept of atomic indivisibility to emphasize that this operation can not be divided .
When using concurrent programming, the critical area needs to be solved ( Modification of public resources ) problem , Abstract data manipulation behavior is RAW,WAR,WAW.🥤🥤🥤 Embodied in the specific coding process , Namely RW, stay RW In the process , No other thread will operate on this critical area . This atomic operation can only be completed by one thread at a time , There are no multiple threads performing atomic operations at the same time .
A simple summary is :
When using atomic operation , It's like crossing a narrow road , A wide alley in the middle . The two ends are so narrow that only one thread is allowed to pass through .
such :

Two 、go Language Atomic Source code analysis and actual operation
go Language Atmoic The related definitions are implemented mainly in sync.Atomic In bag ,Atmoic Low level atomic memory primitives are provided in the package
Used to implement synchronization algorithm .
2.1 Atomic Key functions and their definitions
doc.go It mainly defines SWAP( Exchange operation between variables )、CAS( Variable comparison exchange operation )、ADD( Atomic variable plus operation )、LOAD( Data loading operation of atomic variables )、STORE( Atomic variable storage operation ).
One of the more complicated ones is CAS operation :
Compare and exchange (compare and swap, CAS), It is used to realize uninterrupted data exchange operation in multi-threaded programming , In order to avoid the data inconsistency caused by the uncertainty of execution order and the unpredictability of interrupt when multithreading a certain data at the same time . This operation compares an in-memory value with the specified data , Replace the data in memory with a new value when the value is the same .
Source code interpretation :
Compare the old value with the address in memory , If the old value is equal to the memory address , The memory address has not been modified , You can write the address with the new value .
Input parameter definition :
addr *uint64: Address where data is stored in memory
old: The old value
new uint64: The new value
Back parameter definition :
swapped (TRUE: The exchange was successful ,FALSE: The exchange failed )
// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)CAS Upper ABA problem :
ABA The problem is CAS A common problem , It can be basically expressed as :
- process P1 Read a value A
- P1 suspended ( The time slice runs out 、 Interrupt, etc ), process P2 Start execution
- P2 Modify the value A Is the value B, And then revise it back to A
- P1 Awakened , After comparison, we found the value A There is no change , Program continues
logically CAS It can solve the conflict problem of multi-threaded data exchange , But if the value stored in memory is modified by another thread , And the modified value is the same as the old value . See for specific hazards https://zh.wikipedia.org/zh-cn/%E6%AF%94%E8%BE%83%E5%B9%B6%E4%BA%A4%E6%8D%A2
https://zh.wikipedia.org/zh-cn/%E6%AF%94%E8%BE%83%E5%B9%B6%E4%BA%A4%E6%8D%A2
Complete source code :
package atomic
import (
"unsafe"
)
// BUG(rsc): On 386, the 64-bit functions use instructions unavailable before the Pentium MMX.
//
// On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.
//
// On ARM, 386, and 32-bit MIPS, it is the caller's responsibility
// to arrange for 64-bit alignment of 64-bit words accessed atomically.
// The first word in a variable or in an allocated struct, array, or slice can
// be relied upon to be 64-bit aligned.
// SwapInt32 atomically stores new into *addr and returns the previous *addr value.
func SwapInt32(addr *int32, new int32) (old int32)
// SwapInt64 atomically stores new into *addr and returns the previous *addr value.
func SwapInt64(addr *int64, new int64) (old int64)
// SwapUint32 atomically stores new into *addr and returns the previous *addr value.
func SwapUint32(addr *uint32, new uint32) (old uint32)
// SwapUint64 atomically stores new into *addr and returns the previous *addr value.
func SwapUint64(addr *uint64, new uint64) (old uint64)
// SwapUintptr atomically stores new into *addr and returns the previous *addr value.
func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
// SwapPointer atomically stores new into *addr and returns the previous *addr value.
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.
func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.
func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
// AddInt32 atomically adds delta to *addr and returns the new value.
func AddInt32(addr *int32, delta int32) (new int32)
// AddUint32 atomically adds delta to *addr and returns the new value.
// To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)).
// In particular, to decrement x, do AddUint32(&x, ^uint32(0)).
func AddUint32(addr *uint32, delta uint32) (new uint32)
// AddInt64 atomically adds delta to *addr and returns the new value.
func AddInt64(addr *int64, delta int64) (new int64)
// AddUint64 atomically adds delta to *addr and returns the new value.
// To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)).
// In particular, to decrement x, do AddUint64(&x, ^uint64(0)).
func AddUint64(addr *uint64, delta uint64) (new uint64)
// AddUintptr atomically adds delta to *addr and returns the new value.
func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
// LoadInt32 atomically loads *addr.
func LoadInt32(addr *int32) (val int32)
// LoadInt64 atomically loads *addr.
func LoadInt64(addr *int64) (val int64)
// LoadUint32 atomically loads *addr.
func LoadUint32(addr *uint32) (val uint32)
// LoadUint64 atomically loads *addr.
func LoadUint64(addr *uint64) (val uint64)
// LoadUintptr atomically loads *addr.
func LoadUintptr(addr *uintptr) (val uintptr)
// LoadPointer atomically loads *addr.
func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
// StoreInt32 atomically stores val into *addr.
func StoreInt32(addr *int32, val int32)
// StoreInt64 atomically stores val into *addr.
func StoreInt64(addr *int64, val int64)
// StoreUint32 atomically stores val into *addr.
func StoreUint32(addr *uint32, val uint32)
// StoreUint64 atomically stores val into *addr.
func StoreUint64(addr *uint64, val uint64)
// StoreUintptr atomically stores val into *addr.
func StoreUintptr(addr *uintptr, val uintptr)
// StorePointer atomically stores val into *addr.
func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)

2.1 atomic actual combat
atomic It is relatively simple for basic use , Is the use of atmoc.func To complete the corresponding increase , Assignment operation .
package main
import (
"fmt"
"sync/atomic"
)
func main() {
var operationNums = int32(10)
atomic.AddInt32(&operationNums,12)
fmt.Printf(" Modified value :%d\n",atomic.LoadInt32(&operationNums))
}
2.2 atomic Atomic concurrency
paraphrase : Concurrent modification of variable values , Read the values of variables concurrently .
package main
import (
"fmt"
"sync"
"sync/atomic"
"time"
)
func main() {
var operationNums = int32(10)
group := sync.WaitGroup{}
group.Add(20)
for i := 0; i < 10; i++ {
go func() {
defer group.Done()
time.Sleep(200*time.Millisecond)
atomic.AddInt32(&operationNums,1)
}()
}
for i := 0; i < 10; i++ {
go func(i int) {
defer group.Done()
time.Sleep(200*time.Millisecond)
fmt.Printf(" Threads %d Read the revised values :%d\n",i,atomic.LoadInt32(&operationNums))
}(i)
}
group.Wait()
}
2.3 Atomic operations on arbitrary data structures
adopt var Make a statement atomic.Value Variable of type . Perform related atomic operations on this variable .
package main
import (
"fmt"
"sync"
"sync/atomic"
"time"
)
func main() {
var box atomic.Value
fmt.Println("Copy box to box2.")
v1 := [...]int{1, 2, 3}
fmt.Printf("Store %v to box.\n", v1)
box.Store(v1)
fmt.Printf("The value load from box is %v.\n", box.Load())
fmt.Println()
}Execution results : No one's surprise , It is also the correct implementation .
Copy box to box2.
Store [1 2 3] to box.
The value load from box is [1 2 3].3、 ... and 、 summary
Today I mainly introduce atomic The concept and simple use of , It's more simple . about atomic Application interested students , Can be in go Language related concurrent source code package . Under the source code , No secret . Come on !️~
🧧🧧🧧 Thank you for reading , Pay attention to , Collect it ~
![]()
边栏推荐
- [LeetCode]100. Same tree
- Matlab finds the position of a row or column in the matrix
- The create database of gbase 8A takes a long time to query and is suspected to be stuck
- Day8 - cloud information project introduction and creation
- Solution to the error of VMware tool plug-in installed in Windows 8.1 system
- Remote invocation of microservices
- 记一次List对象遍历及float类型判断大小
- [LeetCode]508. The most frequent subtree elements and
- 百万年薪独家专访,开发人员不修复bug怎么办?
- Interview question 3 of software test commonly used by large factories (with answers)
猜你喜欢

Management system itclub (medium)

Stm32f107+lan8720a use stm32subemx to configure network connection +tcp master-slave +udp app

The "business and Application Security Development Forum" held by the ICT Institute was re recognized for the security capability of Tianyi cloud

使用Fiddler模拟弱网测试(2G/3G)

Educational Codeforces Round 108 (Rated for Div. 2)

Open source technology exchange - Introduction to Chengying, a one-stop fully automated operation and maintenance manager
![[LeetCode]动态规划解分割数组I[Red Fox]](/img/b2/df87c3138c28e83a8a58f80b2938b8.png)
[LeetCode]动态规划解分割数组I[Red Fox]

Fill in the blank of rich text test

《7天学会Go并发编程》第7天 go语言并发编程Atomic原子实战操作含ABA问题

Ellipsis after SQLite3 statement Solutions for
随机推荐
Luogu p5706 redistributing fertilizer and house water
Gbase 8A method for reducing the impact on the system by controlling resource usage through concurrency during node replacement of V8 version
Slow bear market, bit Store provides stable stacking products to help you cross the bull and bear
01 golang environment construction
Software defect management - a must for testers
记一次List对象遍历及float类型判断大小
Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2)
使用sqlite3语句后出现省略号 ... 的解决方法
Gbase 8A OLAP analysis function cume_ Example of dist
BAT测试专家对web测试和APP测试的总结
Ellipsis after SQLite3 statement Solutions for
Gbase 8A OLAP analysis function cume_ Example of dist
OpenSSL programming I: basic concepts
Interval DP of Changyou dynamic programming
Remote invocation of microservices
[LeetCode]513. 找树左下角的值
A method of go accessing gbase 8A database
軟件測試自動化測試之——接口測試從入門到精通,每天學習一點點
MONTHS_ Between function use
使用Jmeter进行性能测试的这套步骤,涨薪2次,升职一次
