0

0

Go 语言中自增操作的原子性与并发安全

DDD

DDD

发布时间:2025-09-25 16:09:35

|

322人浏览过

|

来源于php中文网

原创

go 语言中自增操作的原子性与并发安全

本文探讨了 Go 语言中自增操作在多线程环境下的原子性问题,并给出了在并发场景下保证计数器安全性的两种常用解决方案:使用 atomic 包提供的原子操作函数以及使用 sync.Mutex 互斥锁。通过示例代码详细展示了这两种方法的使用,帮助开发者在并发编程中避免数据竞争,确保程序的正确性。

在 Go 语言中,当多个 Goroutine 并发访问和修改共享变量时,需要特别注意数据竞争的问题。 即使像简单的自增操作 (counter += 1),在多线程环境下也并非原子操作,如果不加保护,会导致意想不到的结果。

自增操作的非原子性

自增操作实际上包含了多个步骤:读取变量的当前值、对值进行加法运算、将结果写回变量。 在多线程环境下,这些步骤可能被其他线程打断,导致数据不一致。 考虑以下场景:

  1. 线程 A 读取 counter 的值为 10。
  2. 线程 B 读取 counter 的值为 10。
  3. 线程 A 将 counter 的值加 1,得到 11,并写回 counter。
  4. 线程 B 将 counter 的值加 1,得到 11,并写回 counter。

最终,counter 的值应该是 12,但实际上却是 11。 这就是数据竞争的典型表现。

解决方案一:使用 atomic 包

Go 语言的 atomic 包提供了一系列原子操作函数,可以保证在多线程环境下对变量的读写操作是原子性的。 对于计数器,可以使用 atomic.AddInt32、atomic.AddInt64 等函数进行原子加法操作。

import "sync/atomic"

var counter int32

// Goroutine 1
func increment() {
    atomic.AddInt32(&counter, 1000)
}

// Goroutine 2
func decrement() {
    atomic.AddInt32(&counter, -512)
}

在上面的例子中,atomic.AddInt32 函数可以原子地将 counter 的值加上 1000 或 -512,避免了数据竞争。 注意,atomic 包的函数需要传入指向变量的指针。

EnablePPA中小学绩效考核系统2.0
EnablePPA中小学绩效考核系统2.0

无论从何种情形出发,在目前校长负责制的制度安排下,中小学校长作为学校的领导者、管理者和教育者,其管理水平对于学校发展的重要性都是不言而喻的。从这个角度看,建立科学的校长绩效评价体系以及拥有相对应的评估手段和工具,有利于教育行政机关针对校长的管理实践全过程及其结果进行测定与衡量,做出价值判断和评估,从而有利于强化学校教学管理,提升教学质量,并衍生带来校长转变管理观念,提升自身综合管理素质。

下载

注意事项:

  • atomic 包提供了多种原子操作函数,如 LoadInt32、StoreInt32、CompareAndSwapInt32 等,可以根据具体需求选择合适的函数。
  • atomic 包的性能通常比使用互斥锁更好,因为原子操作通常由 CPU 指令直接支持,避免了上下文切换的开销。

解决方案二:使用 sync.Mutex

另一种常用的解决方案是使用 sync.Mutex 互斥锁。 互斥锁可以保证在同一时刻只有一个 Goroutine 可以访问共享变量。

import "sync"

var counter int32
var mutex sync.Mutex

func Add(x int32) {
    mutex.Lock()
    defer mutex.Unlock()
    counter += x
}

// Goroutine 1
func increment() {
    Add(1000)
}

// Goroutine 2
func decrement() {
    Add(-512)
}

在上面的例子中,mutex.Lock() 函数会尝试获取锁,如果锁已经被其他 Goroutine 持有,则当前 Goroutine 会阻塞,直到锁被释放。 defer mutex.Unlock() 语句会在函数返回前释放锁,确保锁总是会被释放,即使函数发生 panic。

注意事项:

  • 使用互斥锁需要注意死锁的问题。 例如,如果一个 Goroutine 持有锁 A,同时尝试获取锁 B,而另一个 Goroutine 持有锁 B,同时尝试获取锁 A,则会发生死锁。
  • 互斥锁的性能通常比原子操作差,因为互斥锁涉及到上下文切换。

总结

在 Go 语言中,自增操作在多线程环境下并非原子操作,需要采取措施保证数据安全。 可以使用 atomic 包提供的原子操作函数,或者使用 sync.Mutex 互斥锁。 选择哪种方案取决于具体的应用场景。 如果只需要简单的原子加法操作,atomic 包通常是更好的选择。 如果需要更复杂的同步逻辑,或者需要保护多个变量,则可以使用互斥锁。 在任何情况下,都应该仔细分析并发场景,避免数据竞争和死锁。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

743

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

375

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

28

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

103

2026.02.06

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

3

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

21

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

108

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

51

2026.03.04

热门下载

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

精品课程

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

共32课时 | 5.9万人学习

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

共10课时 | 0.9万人学习

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

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