0

0

Golangsync/atomic原子操作与并发安全

P粉602998670

P粉602998670

发布时间:2025-09-14 08:23:01

|

200人浏览过

|

来源于php中文网

原创

原子操作是不可中断的操作序列,Go的sync/atomic包提供int32、int64等类型的原子操作函数,如Load、Store、Add、Swap和CompareAndSwap,用于实现高效并发安全的计数器、状态标志等场景,避免锁开销。

golangsync/atomic原子操作与并发安全

在Go语言中,sync/atomic包提供了对基本数据类型的原子操作支持,用于实现高效的并发安全访问。当多个goroutine同时读写共享变量时,如果不加保护,就会引发数据竞争(data race),导致程序行为不可预测。虽然可以通过互斥锁(sync.Mutex)来保护共享资源,但在某些简单场景下,使用原子操作更轻量、性能更高。

什么是原子操作?

原子操作是指不可中断的一个或一系列操作,在执行过程中不会被其他goroutine干扰。这意味着对同一个变量的原子读取、写入、增加、比较并交换等操作,在多线程环境下是线程安全的。

Go的sync/atomic主要支持以下类型:

  • int32
  • int64
  • uint32
  • uint64
  • uintptr
  • unsafe.Pointer

注意:没有直接支持float32/float64的原子操作,需要通过atomic.AddUint64配合位操作模拟实现。

立即学习go语言免费学习笔记(深入)”;

常用原子操作函数

以下是sync/atomic中最常用的几个函数及其用途:

  • atomic.LoadInt32(&val):原子读取int32值
  • atomic.StoreInt32(&val, new):原子写入int32值
  • atomic.AddInt32(&val, delta):原子增加,并返回新值
  • atomic.SwapInt32(&val, new):交换值,返回旧值
  • atomic.CompareAndSwapInt32(&val, old, new):如果当前值等于old,则设为new,返回是否成功

这些函数保证了对变量的操作是原子的,避免了使用锁带来的开销。

典型使用场景

原子操作特别适合用于计数器、状态标志、单例初始化等轻量级同步需求。

宽维企业网站管理系统4.0
宽维企业网站管理系统4.0

宽维企业网站管理系统功能说明宽维系列网站管理系统全面免费,个人和商业应用均免费。宽维企业网站管理系统是基于Php+MySql技术开发的企业电子商务平台,全后台操作,无需学习网页制作等知识。前台智能生成页面,可以方便地在线管理、维护、更新您的企业网站。宽维企业网站管理系统安装简单快捷,5分钟就可以安装完成。1 栏目管理方便灵活:可以发布和管理您需要的任何内容的个性栏目。内置数十个功能发布模型,并可以

下载

示例:并发安全的计数器

package main

import (
    "fmt"
    "sync"
    "sync/atomic"
)

func main() {
    var counter int32
    var wg sync.WaitGroup

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            atomic.AddInt32(&counter, 1)
        }()
    }

    wg.Wait()
    fmt.Println("Counter:", atomic.LoadInt32(&counter)) // 输出: Counter: 1000
}

在这个例子中,我们用atomic.AddInt32atomic.LoadInt32来安全地增减和读取计数器,无需互斥锁。

与Mutex的对比

原子操作比互斥锁更快,因为它们通常由底层硬件指令(如CAS、XADD)直接支持,避免了操作系统调度和上下文切换的开销。

但原子操作也有局限性:

  • 只能用于简单类型(不能对结构体整体做原子操作)
  • 逻辑复杂时难以维护,比如需要原子执行多个变量的更新
  • 不适用于临界区较长的操作

因此,如果只是读写一个整型变量或指针,优先考虑原子操作;若涉及复杂逻辑或多字段协调,还是应使用sync.Mutex

常见陷阱与注意事项

  • 确保原子操作的目标变量地址不变,且对齐。Go编译器一般会自动处理,但在结构体中要注意字段顺序。
  • 不要混合使用普通读写和原子操作。例如:
    counter++
    是非原子的,即使变量被声明为原子用途。
  • 64位操作(如int64)在32位平台上可能不是原子的,除非变量是8字节对齐的。Go运行时会对全局变量和分配的对象自动对齐,但栈上变量需注意。

基本上就这些。合理使用sync/atomic能提升程序性能,特别是在高并发场景下对简单共享变量的操作。关键是理解其适用边界,避免误用。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

299

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

75

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

187

2025.07.04

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

386

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

569

2023.08.10

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

4

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.6万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号