当前位置:网站首页>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]动态规划解拆分整数I[Silver Fox]
- Yarn中RMApp、RMAppAttempt、RMContainer和RMNode状态机及其状态转移
- How many ways does selenium upload files? I don't believe you have me all!
- Educational Codeforces Round 108 (Rated for Div. 2)
- Figure countdownlatch and cyclicbarrier based on AQS queue
- [LeetCode]513. Find the value in the lower left corner of the tree
- 《7天学会Go并发编程》第六天 go语言Sync.cond的应用和实现 go实现多线程联合执行
- [sword offer ii] sword finger offer II 029 Sorted circular linked list
- Simulink method for exporting FMU model files
- AQS SOS AQS with me
猜你喜欢
![[LeetCode]动态规划解分割数组I[Red Fox]](/img/b2/df87c3138c28e83a8a58f80b2938b8.png)
[LeetCode]动态规划解分割数组I[Red Fox]

管理系統-ITclub(下)

Slow bear market, bit Store provides stable stacking products to help you cross the bull and bear

深度学习又有新坑了!悉尼大学提出全新跨模态任务,用文本指导图像进行抠图

解决本地连接不上虚拟机的问题

Conversation Qiao Xinyu: l'utilisateur est le gestionnaire de produits Wei Brand, zéro anxiété définit le luxe

Codeforces Round #723 (Div. 2)

Fill in the blank of rich text test

Go from introduction to actual combat - task cancellation (note)

Stm32cubeide1.9.0\stm32cubemx 6.5 f429igt6 plus lan8720a, configure eth+lwip
随机推荐
[LeetCode]161. Edit distance of 1
真香,自从用了Charles,Fiddler已经被我彻底卸载了
渗透学习-靶场篇-dvwa靶场详细攻略(持续更新中-目前只更新sql注入部分)
[LeetCode]515. Find the maximum value in each tree row
mysql 大于 小于 等于符号的表示方法
Educational Codeforces Round 108 (Rated for Div. 2)
大厂常用软件测试面试题三(附答案)
軟件測試自動化測試之——接口測試從入門到精通,每天學習一點點
Dynamic refresh mapper
It smells good. Since I used Charles, Fiddler has been completely uninstalled by me
对话乔心昱:用户是魏牌的产品经理,零焦虑定义豪华
读写分离-Mysql的主从复制
Selenium上传文件有多少种方式?不信你有我全!
Software test automation test -- interface test from entry to proficiency, learn a little every day
年薪50W+的测试大鸟都在用这个:Jmeter 脚本开发之——扩展函数
go语言切片Slice和数组Array对比panic: runtime error: index out of range问题解决
百万年薪独家专访,开发人员不修复bug怎么办?
[LeetCode]572. 另一棵树的子树
Test birds with an annual salary of 50w+ are using this: JMeter script development -- extension function
[Sword Offer II]剑指 Offer II 029. 排序的循环链表
