当前位置: 首页 > article >正文

Golang 中除了加锁还有哪些安全读写共享变量的方式?

Golang 中除了加锁还有哪些安全读写共享变量的方式?

在 Golang 中,除了使用 Mutex 锁来保护共享变量外,还可以通过 Channel原子性操作 来实现安全读写共享变量。
在这里插入图片描述


1. 使用 Channel

原理

Channel 是 Golang 中用于 Goroutine 之间通信的机制。通过 Channel,可以将共享变量的读写操作限制在同一个 Goroutine 中,从而避免数据竞争。

特点
  • 通信代替共享:通过 Channel 传递数据,而不是直接共享变量。
  • 线程安全:Channel 的操作是线程安全的,无需额外的同步机制。
  • 阻塞机制:Channel 的发送和接收操作是阻塞的,确保数据同步。
适用场景
  • 适用于需要 Goroutine 之间通信的场景。
  • 适用于需要解耦数据生产和消费的场景。

2. 使用原子性操作

原理

Golang 的 sync/atomic 包提供了一系列原子操作函数,用于对共享变量进行原子性读写。原子操作是不可分割的,能够确保在并发环境下对共享变量的操作是安全的。

特点
  • 高效:原子操作通常比锁更高效,适合简单的读写操作。
  • 局限性:仅适用于简单的数据类型(如 int32int64 等)。
  • 无阻塞:原子操作不会导致 Goroutine 阻塞。
适用场景
  • 适用于对简单数据类型进行并发读写的场景。
  • 适用于需要高性能的计数器或标志位的场景。

安全读写共享变量
使用 Channel
使用原子性操作
通过 Channel 传递数据
避免直接共享变量
线程安全
使用 sync/atomic 包
原子性读写
高效且无阻塞
代码示例
package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个 Channel 用于传递数据
    ch := make(chan int)

    // 启动一个 Goroutine 写入数据
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i // 发送数据到 Channel
            fmt.Println("Sent:", i)
        }
        close(ch) // 关闭 Channel
    }()

    // 在主 Goroutine 中读取数据
    for value := range ch {
        fmt.Println("Received:", value)
        time.Sleep(500 * time.Millisecond)
    }
}

http://www.kler.cn/a/518684.html

相关文章:

  • 左右互博02-unidbg主动调用外层so函数
  • debian12.9编译freeswitch1.10.12【默认安装】
  • Python “字典” 实战案例:5个项目开发实例
  • Python:元组构造式和字典推导式
  • Spring Boot 3.4 正式发布,结构化日志!
  • 5. 马科维茨资产组合模型+政策意图AI金融智能体(Qwen-Max)增强方案(理论+Python实战)
  • 计算机网络-运输层
  • Golang笔记——GPM调度器
  • 《探秘鸿蒙Next:人工智能助力元宇宙高效渲染新征程》
  • vue2和vue3组件之间的通信方式差异
  • 【C++】特殊类设计、单例模式与类型转换
  • 探秘数据仓库新势力:网络建模
  • 基于微信的原创音乐小程序的设计与实现(LW+源码+讲解)
  • 机器人SLAM建图与自主导航
  • 2025年美赛数学建模B题管理可持续旅游
  • vue3中自定一个组件并且能够用v-model对自定义组件进行数据的双向绑定
  • 如何有效利用数据采集HTTP代理
  • ASP.NET代码审计 SQL注入篇(简单记录)
  • 2024年终总结:技术成长与突破之路
  • CCF开源发展委员会开源供应链安全工作组2025年第1期技术研讨会顺利举行
  • FastDFS的安装及使用
  • LabVIEW心音心电同步采集与实时播放
  • [c语言日寄]结构体的使用及其拓展
  • Arcgis国产化替代:Bigemap Pro正式发布
  • OpenHarmony5.0 AVPlayer新特性开发指导(二)
  • 基于本地事务表+MQ实现分布式事务