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

【Go - sync.once】

sync.Once 是 Go 语言标准库中的一个结构体,它的作用是确保某个操作在全局范围内只被执行一次。这对于实现单例模式或需要一次性初始化资源的场景非常有用。

典型用法

sync.Once 提供了一个方法 Do(f func()),该方法接收一个没有参数和返回值的函数 f 作为参数。无论 Do 方法被调用多少次,函数 f 只会被执行一次。

var once sync.Oncefunc setup() {// 初始化操作,只会执行一次
}func main() {// 即使在多线程环境下,setup函数也只会被执行一次once.Do(setup)once.Do(setup) // 这次调用不会执行setup
}

多CPU下跑 - 示例

依然只执行一次

package mainimport ("fmt""runtime""sync"
)var once sync.Once
var wg sync.WaitGroupfunc setup() {// 初始化操作,只会执行一次fmt.Println("init")
}func main() {// 设置GOMAXPROCS为机器上的CPU核心数// 让协程同时跑在多个CPU上numCPU := runtime.NumCPU()runtime.GOMAXPROCS(numCPU)fmt.Printf("Running with %d CPUs\n", numCPU)// 即使在多核CPU下的多协程环境下,setup函数也只会被执行一次for i := 0; i < 1000; i++ {wg.Add(1)go func(i int) {defer wg.Done()once.Do(setup)fmt.Printf("Running in goroutine %d\n", i)}(i)}wg.Wait()fmt.Println("Done")
}

原理

sync.Once 的实现原理基于 Go 语言的内存模型和同步原语,主要通过两个字段控制:一个是 done,用于标记函数 f 是否已经执行过;另一个是互斥锁 m,用于在多个 goroutine 同时调用 Do 方法时保证只有一个能执行函数 f

  1. Do 方法第一次被调用时,done 字段为 0,表示函数 f 还没有执行。
  2. Do 方法会先检查 done 字段,如果 f 已经执行(done 不为 0),则直接返回。
  3. 如果 f 还没有执行,Do 方法会加锁并再次检查 done 字段,以防在等待锁的过程中 f 被执行。
  4. 如果 f 确实还没有执行,Do 方法会执行函数 f,然后将 done 设置为 1 并释放锁。

这种设计确保了即使在高并发的情况下,函数 f 也只会被执行一次,同时避免了不必要的加锁操作,提高了效率。

http://www.lryc.cn/news/407154.html

相关文章:

  • Spark RPC框架详解
  • win10安装ElasticSearch7.x和分词插件
  • Linux中,MySQL的用户管理
  • 个人电脑网络安全 之 防浏览器和端口溢出攻击 和 权限对系统的重要性
  • 美食聚焦 -- 仿大众点评项目技术难点总结
  • 拓扑图:揭示复杂系统背后的结构与逻辑
  • Java面试八股之什么是spring boot starter
  • 探究项目未能获得ASPICE 1、2级能力的原因及改进策略
  • WHAT - 不同 HTTP Methods 使用场景、使用方法和可能遇到的问题
  • Pytorch使用教学4-张量的索引
  • 【Git多人协作开发】同一分支下的多人协作开发模式
  • Vue使用FullCalendar实现日历/周历/月历
  • 社交圈子聊天交友系统搭建社交app开发:陌生交友发布动态圈子单聊打招呼群聊app介绍
  • 【微信小程序实战教程】之微信小程序原生开发详解
  • PHP身份证实名认证接口集成守护电商购物
  • 为什么有了MAC还需要IP?
  • SpringBoot中如何使用RabbitMq
  • LangChain自定义Embedding封装 之 ERNIE Bot
  • Git 安装教程
  • Lua 类管理器
  • 实现领域驱动设计(DDD)系列详解:领域模型的持久化
  • 配置sublime的中的C++编译器(.sublime-build),实现C++20
  • Android14 - 前台Service、图片选择器 、OpenJDK 17、其他适配
  • 数据恢复教程:如何从硬盘、SD存储卡、数码相机中恢复误删除数据。
  • 谷粒商城实战笔记-47-商品服务-API-三级分类-网关统一配置跨域
  • stm32平台为例的软件模拟时间,代替RTC调试
  • 《设计模式之美》读书笔记2
  • C++ STL set_difference 用法
  • 【基础算法总结】优先级队列
  • python-绝对值排序(赛氪OJ)