Go语言sync包之Pool | 青训营笔记

83 阅读1分钟

3. sync.Pool 原理

sync.Pool 是 Go 语言提供的内置对象池,开箱即用。sync.Pool 的原理非常简单,只有两个方法,Get 和 Put。Get 方法用于获取对象,Put 方法用于放回对象。

sync.Pool 的内部结构如下:

type Pool struct {
    noCopy noCopy
    local     unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
    localSize uintptr        // size of the local array
    localLen  int32
    victim     unsafe.Pointer // local from previous cycle
    victimSize uintptr        // size of victims array
    victimLen  int32
    New func() interface{}
}

sync.Pool 内部有两个指针,local 和 victim,分别用于存储本地的对象和上一轮的对象。local 和 victim 都是 unsafe.Pointer 类型,实际类型是 [P]poolLocal,P 为 CPU 核心数。

3.1 sync.Pool 的 Get 方法

sync.Pool 的 Get 方法用于获取对象,其原型如下:

func (p *Pool) Get() interface{}

Get 方法的实现非常简单,只有两个步骤:

  1. 获取当前 CPU 的 ID
  2. 从 local 中获取对象,如果 local 中不存在,则从 victim 中获取对象,如果 victim 中也不存在,则调用 New 方法创建对象

3.2 sync.Pool 的 Put 方法

sync.Pool 的 Put 方法用于放回对象,其原型如下:

func (p *Pool) Put(x interface{})

Put 方法的实现非常简单,只有两个步骤:

  1. 获取当前 CPU 的 ID
  2. 将对象放回 local 中

4. sync.Pool 的使用

sync.Pool 的使用非常简单,直接声明变量即可,不需要初始化。sync.Pool 的声明如下:

var pool = sync.Pool{}

sync.Pool 的操作如下:

pool.Get() // 获取对象
pool.Put() // 放回对象

5. sync.Pool 的注意事项

  • sync.Pool 不能在创建后再进行复制操作。
  • sync.Pool 与其他结构不同,它不是一个结构体,因此我们在声明的时候只需要声明变量即可,不需要初始化。