golang的sync.Pool的使用

栏目: Go · 发布时间: 6年前

内容简介:这个玩意的出现是为了解决 gc 的问题, 核心点在于 重用对象, 提高性能. 减少内存的分配.下面看个例子输出

这个玩意的出现是为了解决 gc 的问题, 核心点在于 重用对象, 提高性能. 减少内存的分配.

下面看个例子

package main

import (
    "sync"
    "fmt"
)

func main() {
    p := &sync.Pool{
        New: func() interface{} {
            return 0
        },
    }

    a := p.Get().(int)
    fmt.Println(a)
    p.Put(1)
    p.Put(4)
    p.Put(2)
    p.Put(5)

    b := p.Get().(int)
    // runtime.GC()  // 执行回收操作后 1 0 0 0
    c := p.Get().(int)
    d := p.Get().(int)
    fmt.Println(b, c, d, p.Get())
}

输出

0
1 5 2 4   // 神奇的输出

总结一下文章里面说的

1. 缓存对象没有数量限制 即只受制于物理限制 - 内存
2. 缓存对象的过期  注册了  runtime_registerPoolCleanup(poolCleanup) 函数,  每次gc之前都会调用.
sync.Pool的缓存的期限只是在两次gc之间...  因此不能实现socket连接池.

这真是一个有意思的小程序. = - =. 研究了好久才明白的 . 无私分享一下...

package main

import (
    "sync"
    "fmt"
    "runtime"
    "time"
)

func main() {
    p := &sync.Pool{
        New: func() interface{} {
            return 0
        },
    }

    runtime.GOMAXPROCS(2)

    a := p.Get().(int)
    fmt.Println(a)
    p.Put(1)

    wg := sync.WaitGroup{}
    wg.Add(1)
    go func(){
        defer wg.Done()
        p.Put(100)
    }()
    wg.Wait()

    time.Sleep(time.Second * 1)

    p.Put(4)
    p.Put(5)

    fmt.Println(p.Get())
    fmt.Println(p.Get())
    fmt.Println(p.Get())
        // fmt.Println(p.Get())
}

有趣的输出结果

是不是很有趣. 这里解释一下. 首先我们要搞清楚的一些概念

  1. 这个sync.Pool的缓存是每一个 P 有一个私有对象, 然后有一个共享列表对象.
  2. 每次Get的时候优先取自己 P的私有对象, 然后取自己P的共享列表对象, 且取共享的时候是 先进后出的栈. 最后取别的P的共享列表对象, 但是取不到别人的私有对象...
  3. time.Sleep 可能会让goroutine 切换 P执行
  4. 这里程序注册了2个P
1: 0 1 5 4    // P1私有设置了 1 , 然后 goroutine在第二个上执行, P2私有设置了 100, 然后 4, 5 分别被塞到了 P1的共享变量里... 也就意味着最后的Get是在P1 执行的. 所以先取私有  1 ,  然后共享先进后出 5  4 
// P1 私->1  P1 公 -> 100, 4, 5  => 100没取出来.

2: 0 100 5 4 // P1 私 -> 1,  P2 私 -> 100 ,  P2 公 -> 4 , 5 最后在P2上执行.

3: 0 4 5 100  //  P1 私 -> 1,  P1公 -> 100 ,  P2 私 -> 4  P2 公 -> 5  最后在P2上执行.    4 . 5 . 100

有趣吧~ 这个pool的对象是跟P绑定的~ goroutine 走掉了 但是他留下了 put的私有变量 ~~~

可以把上面最后一行的 打印打开. ~ 大家可以试下结果 . 每种结果出现的概率不一样. 需要多跑几次.

测试时 go 1.11版本

+++ 备注

gc会回收pool里的东西 , 这个pool只是增加了对象重用的机会~~~


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Weaving the Web

Weaving the Web

Tim Berners-Lee / Harper Paperbacks / 2000-11-01 / USD 15.00

Named one of the greatest minds of the 20th century by Time , Tim Berners-Lee is responsible for one of that century's most important advancements: the world wide web. Now, this low-profile genius-wh......一起来看看 《Weaving the Web》 这本书的介绍吧!

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具