阅读golang sync.Once文档
This commit is contained in:
@@ -1,3 +1,46 @@
|
|||||||
|
- [Golang](#golang)
|
||||||
|
- [Get Started](#get-started)
|
||||||
|
- [Enable dependency tracking](#enable-dependency-tracking)
|
||||||
|
- [go mod init](#go-mod-init)
|
||||||
|
- [go mod tidy](#go-mod-tidy)
|
||||||
|
- [multi-module workspace](#multi-module-workspace)
|
||||||
|
- [go work init](#go-work-init)
|
||||||
|
- [go work use](#go-work-use)
|
||||||
|
- [Gin框架构建restful api](#gin框架构建restful-api)
|
||||||
|
- [向response中写入返回数据](#向response中写入返回数据)
|
||||||
|
- [解析request中的数据](#解析request中的数据)
|
||||||
|
- [将请求的endpoint注册到server中](#将请求的endpoint注册到server中)
|
||||||
|
- [golang generic](#golang-generic)
|
||||||
|
- [不使用泛型的代码编写](#不使用泛型的代码编写)
|
||||||
|
- [使用泛型的代码编写](#使用泛型的代码编写)
|
||||||
|
- [comparable](#comparable)
|
||||||
|
- [泛型方法调用](#泛型方法调用)
|
||||||
|
- [type constraint](#type-constraint)
|
||||||
|
- [Fuzzing](#fuzzing)
|
||||||
|
- [unit test编写](#unit-test编写)
|
||||||
|
- [fuzz test编写](#fuzz-test编写)
|
||||||
|
- [执行fuzz test](#执行fuzz-test)
|
||||||
|
- [sync.Pool](#syncpool)
|
||||||
|
- [sync.Pool使用示例](#syncpool使用示例)
|
||||||
|
- [Pool和垃圾回收](#pool和垃圾回收)
|
||||||
|
- [poolCleanup](#poolcleanup)
|
||||||
|
- [allPools \& oldPools](#allpools--oldpools)
|
||||||
|
- [Proc Pining](#proc-pining)
|
||||||
|
- [per-P](#per-p)
|
||||||
|
- [local \& localSize](#local--localsize)
|
||||||
|
- [PinSlow](#pinslow)
|
||||||
|
- [Pool Local](#pool-local)
|
||||||
|
- [pool的Put/Get](#pool的putget)
|
||||||
|
- [Put](#put)
|
||||||
|
- [Get](#get)
|
||||||
|
- [slow path](#slow-path)
|
||||||
|
- [Sync.once](#synconce)
|
||||||
|
- [use case](#use-case)
|
||||||
|
- [syntax](#syntax)
|
||||||
|
- [iota](#iota)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Golang
|
# Golang
|
||||||
## Get Started
|
## Get Started
|
||||||
### Enable dependency tracking
|
### Enable dependency tracking
|
||||||
@@ -310,8 +353,7 @@ ok git.kazusa.red/asahi/fuzz-demo 10.360s
|
|||||||
> #### new interesting
|
> #### new interesting
|
||||||
> `new interesting`指会扩充code coverage的用例输入,在fuzz test刚开始时,new interesting数量通常会因发现新的代码路径快速增加,然后,会随着时间的推移逐渐减少
|
> `new interesting`指会扩充code coverage的用例输入,在fuzz test刚开始时,new interesting数量通常会因发现新的代码路径快速增加,然后,会随着时间的推移逐渐减少
|
||||||
|
|
||||||
## Go Sync
|
## sync.Pool
|
||||||
### sync.Pool
|
|
||||||
`sync.Pool`为golang标准库中的实现,用于降低allocation和减少垃圾回收。
|
`sync.Pool`为golang标准库中的实现,用于降低allocation和减少垃圾回收。
|
||||||
|
|
||||||
### sync.Pool使用示例
|
### sync.Pool使用示例
|
||||||
@@ -708,6 +750,61 @@ func (p *Pool) getSlow(pid int) any {
|
|||||||
- 如果所有victim中的poolLocal对象都返回为空,那么会将victim中`p.victimSize`标识为空,后续再次执行slow path时,如果感知到victimSize为空,那么便不会再次查找victim
|
- 如果所有victim中的poolLocal对象都返回为空,那么会将victim中`p.victimSize`标识为空,后续再次执行slow path时,如果感知到victimSize为空,那么便不会再次查找victim
|
||||||
|
|
||||||
|
|
||||||
|
## Sync.once
|
||||||
|
sync.Once是golang中提供的工具包,确保指定的代码块在并发环境下只会被执行一次。
|
||||||
|
|
||||||
|
sync.Once为struct,其中只包含一个方法`Do(f func())`。sync.Once保证指定方法只会被执行一次,即使在多routine环境下被调用了多次。`并且,sync.Once方法是线程安全的`。
|
||||||
|
|
||||||
|
### use case
|
||||||
|
sync.Once的用例如下:
|
||||||
|
- 对共享的资源进行初始化
|
||||||
|
- 设置单例
|
||||||
|
- 执行只需要运行一次的高开销计算
|
||||||
|
- 导入配置文件
|
||||||
|
|
||||||
|
sync.Once的使用示例如下:
|
||||||
|
```go
|
||||||
|
var instance *singleton
|
||||||
|
var once sync.Once
|
||||||
|
|
||||||
|
func getInstance() *singleton {
|
||||||
|
once.Do(func() {
|
||||||
|
instance = &singleton{}
|
||||||
|
})
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
sync.Once实现逻辑如下:
|
||||||
|
```go
|
||||||
|
type Once struct {
|
||||||
|
// done indicates whether the action has been performed.
|
||||||
|
// It is first in the struct because it is used in the hot path.
|
||||||
|
// The hot path is inlined at every call site.
|
||||||
|
// Placing done first allows more compact instructions on some architectures (amd64/386),
|
||||||
|
// and fewer instructions (to calculate offset) on other architectures.
|
||||||
|
done atomic.Uint32
|
||||||
|
m Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Once) Do(f func()) {
|
||||||
|
|
||||||
|
if o.done.Load() == 0 {
|
||||||
|
// Outlined slow-path to allow inlining of the fast-path.
|
||||||
|
o.doSlow(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Once) doSlow(f func()) {
|
||||||
|
o.m.Lock()
|
||||||
|
defer o.m.Unlock()
|
||||||
|
if o.done.Load() == 0 {
|
||||||
|
defer o.done.Store(1)
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## syntax
|
## syntax
|
||||||
### iota
|
### iota
|
||||||
`iota`关键字代表连续的整数变量,`0, 1, 2`,每当`const`关键字出现时,其重置为0
|
`iota`关键字代表连续的整数变量,`0, 1, 2`,每当`const`关键字出现时,其重置为0
|
||||||
|
|||||||
Reference in New Issue
Block a user