golang的sync.Pool的使用

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

内容简介:这个玩意的出现是为了解决 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只是增加了对象重用的机会~~~


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

查看所有标签

猜你喜欢:

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

科技之巅2

科技之巅2

麻省理工科技评论 / 人民邮电出版社 / 2017-6-1 / CNY 88.00

《麻省理工科技评论》从2001年开始,每年都会公布“10大全球突破性技术”,即TR10(Technology Review 10),并预测其大规模商业化的潜力,以及对人类生活和社会的重大影响。 这些技术代表了当前世界科技的发展前沿和未来发展方向,集中反映了近年来世界科技发展的新特点和新趋势,将引领面向未来的研究方向。其中许多技术已经走向市场,主导着产业技术的发展,极大地推动了经济社会发展和科技创新......一起来看看 《科技之巅2》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

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

RGB CMYK 互转工具