zoukankan      html  css  js  c++  java
  • go中sync.Once源码解读

    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、完成。

  • 相关阅读:
    DOM_节点操作创建表格
    表单提交
    HTML常用标签
    网络通讯详解
    java===TCP(多线程多客户端同时上传字节数据:图片为例)
    java===TCP(文件上传功能)
    java===UDP
    java==IO=随机读写文件
    git中的基本命令
    ansible中roles的简单使用
  • 原文地址:https://www.cnblogs.com/ricklz/p/14503674.html
Copyright © 2011-2022 走看看