sync.Once

前言

本次的代码是基于go version go1.13.15 darwin/amd64

sync.Once的作用

根据名字就大致能猜到这个函数的作用,就是使用sync.once的对象只能执行一次。

我们在errgroup就能看到它的身影

type Group struct {
cancel func() wg sync.WaitGroup errOnce sync.Once
err error
}

他保证了,只会记录第一个出错的goroutine的错误信息

实现原理

// Once is an object that will perform exactly one action.
type Once struct {
// 0未执行,1执行了
done uint32
// 互斥锁
m Mutex
}

里面就一个对外的函数

func (o *Once) Do(f func()) {
// 原子的读取done的值,如果为0代表onec第一次的执行还没有出发
if atomic.LoadUint32(&o.done) == 0 {
// 执行
o.doSlow(f)
}
} func (o *Once) doSlow(f func()) {
// 加锁
o.m.Lock()
defer o.m.Unlock()
// 判断done变量为0表示还没执行第一次
if o.done == 0 {
// 计数器原子的加一
defer atomic.StoreUint32(&o.done, 1)
// 执行传入的函数
f()
}
}

总结

1、总体上也是很简单一个计数器,一把互斥锁,通过atomic.LoadUint32的原子读取技术器中的值;

2、如果计数器中的值为0表示还没有执行;

3、加锁,执行传入的函数,然后通过atomic.StoreUint32原子的对计数器的值进行加一操作;

4、完成。

go中sync.Once源码解读的更多相关文章

  1. go中sync.Mutex源码解读

    互斥锁 前言 什么是sync.Mutex 分析下源码 Lock 位运算 Unlock 总结 参考 互斥锁 前言 本次的代码是基于go version go1.13.15 darwin/amd64 什么 ...

  2. go中sync.Cond源码解读

    sync.Cond 前言 什么是sync.Cond 看下源码 Wait Signal Broadcast 总结 sync.Cond 前言 本次的代码是基于go version go1.13.15 da ...

  3. go中semaphore(信号量)源码解读

    运行时信号量机制 semaphore 前言 作用是什么 几个主要的方法 如何实现 sudog 缓存 acquireSudog releaseSudog semaphore poll_runtime_S ...

  4. java jdk 中HashMap的源码解读

    HashMap是我们在日常写代码时最常用到的一个数据结构,它为我们提供key-value形式的数据存储.同时,它的查询,插入效率都非常高. 在之前的排序算法总结里面里,我大致学习了HashMap的实现 ...

  5. Alamofire源码解读系列(四)之参数编码(ParameterEncoding)

    本篇讲解参数编码的内容 前言 我们在开发中发的每一个请求都是通过URLRequest来进行封装的,可以通过一个URL生成URLRequest.那么如果我有一个参数字典,这个参数字典又是如何从客户端传递 ...

  6. JDK容器类Map源码解读

    java.util.Map接口是JDK1.2开始提供的一个基于键值对的散列表接口,其设计的初衷是为了替换JDK1.0中的java.util.Dictionary抽象类.Dictionary是JDK最初 ...

  7. etcd学习(6)-etcd实现raft源码解读

    etcd中raft实现源码解读 前言 raft实现 看下etcd中的raftexample newRaftNode startRaft serveChannels 领导者选举 启动并初始化node节点 ...

  8. 【原】Spark中Job的提交源码解读

    版权声明:本文为原创文章,未经允许不得转载. Spark程序程序job的运行是通过actions算子触发的,每一个action算子其实是一个runJob方法的运行,详见文章 SparkContex源码 ...

  9. HttpServlet中service方法的源码解读

    前言     最近在看<Head First Servlet & JSP>这本书, 对servlet有了更加深入的理解.今天就来写一篇博客,谈一谈Servlet中一个重要的方法-- ...

随机推荐

  1. 2017, X Samara Regional Intercollegiate Programming Contest M. Last Man Standing (贪心,双指针)

    题意:有\(n\)个吃鸡玩家,在某个时间段给你他们每个人的杀敌数,判断数据是否合法,并输出每个人对应的杀敌情况. 题解:刚开始写的是直接暴力枚举,向后去找并且标记,然后存到vector最后输出,结果一 ...

  2. MySQL 连接管理

    目录 MySQL 连接方式 TCP/IP 连接 Socket 连接 MySQL 连接工具 自带连接工具 第三方连接工具 MySQL 连接方式 TCP/IP 连接 # TCP/IP 连接 mysql - ...

  3. 免费在线 Linux Desktop 环境

    免费在线 Linux Desktop 环境 Run Linux OS Distributions online https://www.onworks.net/os-distributions 免费测 ...

  4. macOS 升级后导致 dart bug

    macOS 升级后导致 dart bug macOS 10.15.5 $ demo_app git:(master) flutter doctor # /Users/xgqfrms-mbp/Docum ...

  5. navigator.geolocation.getCurrentPosition

    navigator.geolocation.getCurrentPosition Geolocation API Specification 2nd Edition W3C Recommendatio ...

  6. Netty & websockets

    Netty & websockets Netty is a non-blocking I/O client-server framework for the development of Ja ...

  7. SMS OTP 表单最佳做法 (短信验证)

    <form action="/verify-otp" method="POST"> <input type="text" ...

  8. Objec.assign & bug

    Objec.assign & bug shallow copy https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Referenc ...

  9. nasm aat函数 x86

    xxx.asm: %define p1 ebp+8 %define p2 ebp+12 %define p3 ebp+16 section .text global dllmain dllmain: ...

  10. c++ string split function

    #include <string> #include <vector> #include <regex> struct SplitListItem { std::s ...