[Golang]同步工具-sync包的Pool(下)-心智图总结

1. 池清理函数
Go语言运行时系统中的垃圾回收器,在每次开始执行之前,都会对所有已创建的临时对象池中的值进行全面性的清除。
(sync包在被初始化的时候,会向Go语言运行时系统注册一个函数,这个函数的功能就是清除,所有已创建的临时对象池。)

2. 池滙总列表
在sync包中,有一个包级私有的全域变数。这个变数代表当前的程序中使用的所有临时对象池滙总。可以称为池滙总列表。在一个临时对象池的Get方法和Put方法第一次被呼叫的时候,这个池就会被添加到池滙总列表中。
如此,池清理函数能访问到所有正在被使用的临时对象池。

3. 本地池、私有临时对象、共享临时对象列表的关系
在本地池列表中,每个本地池都包含三个字段,它们是储存私有临时对象的字段private、共享临时对象列表的字段shared,以及一个sync.Mutex类型的嵌入字段。

4. 临时对象池,是怎样利用内部数据结构来存取值?
临时对象池的Put方法,会先试图把新的临时对象,储存到对应的本地池的private字段中,以便在後面要Get临时对象的时候,可以拿到一个可以用的值。
只有当这个private字段已经存有某个值时,Put方法才会去访问本地池的shared字段。

当Put方法,发现本地池的private字段已经有值,就会去访问本地池的shared字段。
由於shared字段是共享的,所以此时必须受到互斥锁的保护,才能把新的临时对象追加到共享临时对象的列表末尾。
(本地池嵌入的sync.Mutex类型的字段)

临时对象池的Get方法,会先试图从对应的本地池的private字段取得一个临时对象。
只有当这个private字段的值为nil时,它才会去访问本地池的shared字段。

当Get方法,发现本地池的private字段没有值时,就会访问shared字段。会在互斥锁的保护下,取出共享临时对象列表的最後一个元素。
如果Get方法,发现所有的临时对象池,都是空的,就会呼叫临时对象池的New字段的函数,如果这个字段的值是nil,那就回传nil。

  1. 一个本地池的shared字段原则上可以被任何goroutine中的代码访问到,不论这个goroutine关联是哪一个P
    而一个本地池的private字段,只能被goroutine所关联的P访问到。(P级私有)

https://ithelp.ithome.com.tw/upload/images/20201208/201317281et8HbnqcL.png

https://ithelp.ithome.com.tw/upload/images/20201208/20131728NEwNqWpez2.png

参考来源:
郝林-Go语言核心36讲
https://github.com/hyper0x/Golang_Puzzlers
https://golang.org/pkg/cmd/go/internal/test/


<<:  [Golang]同步工具-sync包的Pool(上)-心智图总结

>>:  安全设计原则分类(taxonomy of security design principles)

第廿六日:终於旅游感满满的周日

早上起来,决定至少去吸食一下咖啡,买个包子,看看时间已经八点半,出发。 顺着中华路走到中山路,然後拐...

容器化的安全原则(the security principles of containerization)

-容器技术架构 容器映像是由开发人员创建和注册的包,其中包含在容器中运行所需的所有文件,通常按层组...

[Day 29]老师我学逻辑推论做什麽(4)

36:所以老师我学逻辑推论到底要做什麽呢 RN:我觉得只是因为学校一味的叫你们证明东证明西所以才让你...

#30 No-code 之旅 — 恭喜完赛!

最後一天!礼拜五快乐!恭喜大家完赛!恭喜自己XD 今天来回头看看我们这三十天学了哪些事,还有讲一下未...

[Day 18 - webpack] 模组化开发好帮手 — 打包工具 webpack

为什麽要使用 webpack? 在前一篇文章提到,有愈来愈多开源套件,可以帮助我们加速开发。当功能愈...