使用atomic包可避免数据竞争并提升性能,适用于计数器等场景。通过atomic.AddInt64等函数实现无锁并发安全操作,相比互斥锁更轻量高效。

在Go语言中,多协程环境下对共享变量的操作容易引发数据竞争问题。为避免使用互斥锁(sync.Mutex)带来的性能开销和复杂性,Go的sync/atomic包提供了对基本数据类型的原子操作支持。合理使用atomic不仅能提升性能,还能简化并发控制逻辑。
sync/atomic主要支持整型(int32、int64、uint32、uint64)、指针、uintptr 和 bool 类型的原子操作。常用函数包括:
这些操作保证了在多协程并发访问时不会出现中间状态,适合计数器、状态标志等场景。
最常见的用途是实现一个线程安全的计数器。相比使用互斥锁,atomic更轻量。
立即学习“go语言免费学习笔记(深入)”;
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int64
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
atomic.AddInt64(&counter, 1)
}()
}
wg.Wait()
fmt.Println("Counter:", atomic.LoadInt64(&counter)) // 输出: Counter: 1000
}
在这个例子中,每个goroutine对counter执行原子加1,最终结果准确无误,且没有使用锁。
Compare-And-Swap(CAS)可用于实现无锁的状态切换,比如服务启动/关闭标志。
var status int32
func tryStart() bool {
return atomic.CompareAndSwapInt32(&status, 0, 1)
}
func stop() {
atomic.StoreInt32(&status, 0)
}
func getStatus() string {
if atomic.LoadInt32(&status) == 1 {
return "running"
}
return "stopped"
}
tryStart函数确保只有一个调用者能将状态从0改为1,常用于单例初始化或防重复执行。
虽然atomic高效,但也有使用限制:
基本上就这些。atomic适合简单共享状态的高性能并发控制,掌握Load、Store、Add、CAS四个核心操作,就能应对大多数无锁编程场景。
以上就是Golang使用atomic进行原子操作实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号