IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> golang的pool在公共组件里的使用 -> 正文阅读

[C++知识库]golang的pool在公共组件里的使用

1、part1 一个例子

? ?

 p := pool.Get().(*Person)
?? ?fmt.Printf("第一次从pool里拿对象, %+v \n", p)
?? ?p.Name = "HanMeiMei"
?? ?pool.Put(p)
?? ?fmt.Printf("pool里已经有一个对象, %+v \n", pool.Get().(*Person))
?? ?fmt.Printf("pool里已经没有对象了, %+v \n", pool.Get().(*Person))
?? ?L()

? ?2、part2 golang里fmt.Printf如何使用sync.Pool

fmt.Printf中Printf对应的函数是:


?

        func Printf(format string, a ...interface{}) (n int, err error) {
?? ??? ??? ?return Fprintf(os.Stdout, format, a...)
?? ??? ?}

?? ??? ?继续看Fprintf函数:

?? ??? ?func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
?? ??? ??? ?p := newPrinter()
?? ??? ??? ?p.doPrintf(format, a)
?? ??? ??? ?n, err = w.Write(p.buf)
?? ??? ??? ?p.free()
?? ??? ??? ?return
?? ??? ?}

?? ??? ?Fprintf第一个参数是io.Writer,Printf函数里传的是os.Stdout,相当于直接输出到标准输出。这里的newPrinter就是调用的Pool,
?? ??? ?拿到pp指针之后,首先是做了一些format操作。并且将p.buf的内容写到w,调用free()函数将p重新归还到pool里。归还之前将p的部分字段重置,以便于其它代码再次拿到这个对象时是“干净”的。

?其中newPrinter对应的函数体是
?? ???

 ?func newPrinter() *pp {
?? ??? ??? ?p := ppFree.Get().(*pp)
?? ??? ??? ?p.panicking = false
?? ??? ??? ?p.erroring = false
?? ??? ??? ?p.wrapErrs = false
?? ??? ??? ?p.fmt.init(&p.buf)
?? ??? ??? ?return p
?? ??? ?}

函数体里ppFree是一个变量,对应一个sync.Pool
?? ???

 ?var ppFree = sync.Pool{
?? ??? ??? ?New: func() interface{} { return new(pp) },
?? ??? ?}

结构体pp保存了一个打印对象的状态并且被sync.Pool重用以防止出现内存分配瓶颈。

接下来我们看一下pool_test.go的TestPoolNew函数 在src/sync/pool_test.go
?? ??? ??? ?

func TestPoolNew(t *testing.T) {
?? ??? ??? ??? ?// disable GC so we can control when it happens.
?? ??? ??? ??? ?// 首先设置了GC=-1,就是不去做GC
?? ??? ??? ??? ?defer debug.SetGCPercent(debug.SetGCPercent(-1))

?? ??? ??? ??? ?i := 0
?? ??? ??? ??? ?p := Pool{
?? ??? ??? ??? ??? ?New: func() interface{} {
?? ??? ??? ??? ??? ??? ?i++
?? ??? ??? ??? ??? ??? ?return i
?? ??? ??? ??? ??? ?},
?? ??? ??? ??? ?}

?? ??? ??? ??? ?// 此时pool里为空,连续调用两次Get,会返回1、2
?? ??? ??? ??? ?if v := p.Get(); v != 1 {
?? ??? ??? ??? ??? ?t.Fatalf("got %v; want 1", v)
?? ??? ??? ??? ?}
?? ??? ??? ??? ?if v := p.Get(); v != 2 {
?? ??? ??? ??? ??? ?t.Fatalf("got %v; want 2", v)
?? ??? ??? ??? ?}

?? ??? ??? ??? ?// 防止goroutine被抢占,目的是保护接下来的Put和Get操作都是同一个P的池子
?? ??? ??? ??? ?Runtime_procPin()
?? ??? ??? ??? ?p.Put(42)
?? ??? ??? ??? ?if v := p.Get(); v != 42 {
?? ??? ??? ??? ??? ?t.Fatalf("got %v; want 42", v)
?? ??? ??? ??? ?}
?? ??? ??? ??? ?Runtime_procUnpin()

?? ??? ??? ??? ?if v := p.Get(); v != 3 {
?? ??? ??? ??? ??? ?t.Fatalf("got %v; want 3", v)
?? ??? ??? ??? ?}
?? ??? ??? ?}


?? ??? ?type PoolDequeue interface {
?? ??? ??? ?PushHead(val interface{}) bool
?? ??? ??? ?PopHead() (interface{}, bool)
?? ??? ??? ?PopTail() (interface{}, bool)
?? ??? ?}

PoolDequeue 是一个双端队列,可以从头入队元素也可以从头、尾出队元素。

?3、?gin框架也用到了sync.Pool


?? ?github.com\gin-gonic\gin\gin.go

func New() *Engine {
?? ?...
?? ?engine.pool.New = func() interface{} {
?? ??? ??? ?return engine.allocateContext()
?? ??? ?}
?? ?}

?? ?func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
?? ??? ?c := engine.pool.Get().(*Context)
?? ??? ?c.writermem.reset(w)
?? ??? ?c.Request = req
?? ??? ?c.reset()

?? ??? ?engine.handleHTTPRequest(c)

?? ??? ?engine.pool.Put(c)
?? ?}
?? ?


?? ?
?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-01 17:31:50  更:2021-12-01 17:32:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:53:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码