go源码分析
nevermoress
https://github.com/nevermoressss/note 我的一些学习笔记
展开
-
golang 源码分析之select
select 让 Goroutine 同时等待多个 Channel 的可读或者可写. 在多个文件或者 Channel 发生状态改变之前,select 会一直阻塞当前线程或者 Goroutine。 select 是一种与 switch 相似的控制结构。 select 中虽然也有多个 case,但是这些 case 中的表达式必须都是 Channel 的收发操作。 scase:runtime.scase(select 控制结构中的 case ) type scase struct { c原创 2020-11-17 14:36:39 · 268 阅读 · 0 评论 -
golang 源码分析之 网络轮询器
网络轮询器 为了提高 I/O 多路复用的性能,不同的操作系统也都实现了自己的 I/O 多路复用函数, 例如:epoll、kqueue 和 evport 等。 Go 语言为了提高在不同操作系统上的 I/O 操作性能,使用平台特定的函数实现了多个版本的网络轮询模块 src/runtime/netpoll_epoll.go src/runtime/netpoll_kqueue.go src/runtime/netpoll_solaris.go src/runtime/netpoll_windows.go src/原创 2020-11-17 14:36:06 · 505 阅读 · 1 评论 -
golang 源码分析之scheduler调度器
单线程调度器 · 0.x 只包含 40 多行代码; 程序中只能存在一个活跃线程,由 G-M 模型组成; 多线程调度器 · 1.0 允许运行多线程的程序; 全局锁导致竞争严重; 任务窃取调度器 · 1.1 引入了处理器 P,构成了目前的 G-M-P 模型; 在处理器 P 的基础上实现了基于工作窃取的调度器; 在某些情况下,Goroutine 不会让出线程,进而造成饥饿问题; 时间过长的垃圾回收(Stop-the-world,STW)会导致程序长时间无法工作; 抢占式调度器 · 1.2 ~ 至今 基于协作的抢占原创 2020-11-17 14:35:16 · 372 阅读 · 0 评论 -
golang 源码分析之channel
channel channel分为有阻塞的和无阻塞的,其实关键就是在于是否有capacity。 已关闭的channal再次关闭会触发panic注意下 已关闭的channal发送消息,会触发panic 分析: 先在runtime包里找到chan.go type hchan struct { //队列中目前的元素计数 qcount uint // total data in the queue //环形队列的总大小 dataqsiz uint // si原创 2020-11-17 14:34:37 · 287 阅读 · 0 评论 -
golang 源码分析之sync
sync 同步 sync.Mutex sync.RWMutex sync.WaitGroup sync.Once sync.Cond Mutex // A Mutex must not be copied after first use. type Mutex struct { state int32 sema uint32 } mutex.Lock() func (m *Mutex) Lock() { // 先看看能不能直接获取到 if atomic.CompareAndSwapInt32(原创 2020-11-17 14:34:04 · 153 阅读 · 0 评论 -
golang 源码分析之context
context 上下文 context.Context 是用来设置截止日期、同步信号,传递请求相关值的结构体。 该接口定义了四个需要实现的方法 Deadline — 返回 context.Context 被取消的时间,也就是完成工作的截止日期; Done — 返回一个 Channel,这个 Channel 会在当前工作完成或者上下文被取消之后关闭,多次调用 Done 方法会返回同一个 Channel; Err — 返回 context.Context 结束的原因,它只会在 Done 返回的 Channel原创 2020-11-17 14:33:17 · 107 阅读 · 0 评论 -
golang 源码分析之interface
概述 接口的本质就是引入一个新的中间层,调用方可以通过接口与具体实现分离,解除上下游的耦合,上层的模块不再需要依赖下层的具体模块,只需要依赖一个约定好的接口。 在 Go 中:实现接口的所有方法就隐式的实现了接口;Go 语言中接口的实现都是隐式的 接口也是 Go 语言中的一种类型,它能够出现在变量的定义、函数的入参和返回值中并对它们进行约束,不过 Go 语言中有两种略微不同的接口,一种是带有一组方法的接口,另一种是不带任何方法的 interface{} 不包含任何方法的 interface{} 类型 efac原创 2020-11-16 17:51:00 · 200 阅读 · 0 评论 -
golang 源码分析之panic&recover
panic&recover panic 能够改变程序的控制流,函数调用panic 时会立刻停止执行函数的其他代码,并在执行结束后在当前 Goroutine 中递归执行调用方的延迟函数调用 defer recover 可以中止 panic 造成的程序崩溃。它是一个只能在 defer 中发挥作用的函数,在其他作用域中调用不会发挥任何作用 panic 只会触发当前 Goroutine 的延迟函数调用; recover 只有在 defer 函数中调用才会生效; panic 允许在 defer 中嵌套多次原创 2020-11-16 17:49:58 · 160 阅读 · 0 评论 -
golang 源码分析之defer
defer Go 语言的 defer 会在当前函数或者方法返回之前执行传入的函数。 它会经常被用于关闭文件描述符、关闭数据库连接以及解锁资源。 Go 语言 defer 语句的三种机制(来源网络) Golang 的 1.13 版本 与 1.14 版本对 defer 进行了两次优化 堆上分配 在 Golang 1.13 之前的版本中,所有 defer 都是在堆上分配,该机制在编译时会进行两个步骤: 1、在 defer 语句的位置插入 runtime.deferproc,当被执行时,延迟原创 2020-11-16 17:48:45 · 275 阅读 · 0 评论 -
golang 源码分析之string
string Go 语言中的字符串其实是一个只读的字节数组 string 对应的结构 type StringHeader struct { Data uintptr //指向底层数据 Len int //长度 } type stringStruct struct { str unsafe.Pointer len int } 字符串拼接 concatstrings:runtime/concatstrings func concatstrings(buf *tmpBuf,原创 2020-11-16 17:47:21 · 297 阅读 · 0 评论 -
golang 源码分析之map
map的实现原理:hash hash表 O(1) 的读写性能非常优秀,提供了键值之间的映射。 hash 的性能好不好主要看2点 :哈希函数和冲突解决方法 go中利用拉链法实现哈希表 装载因子:=元素数量 / 桶数量 扩容后数据的迁移:只会发生在删除和写入过程,查询没有 hmap : runtime/map.hmap // A header for a Go map. type hmap struct { // 当前的数量 count int // # live cells == size of原创 2020-11-16 17:46:18 · 165 阅读 · 0 评论 -
golang 源码分析之slice
切片 切片就是动态数组,它的长度并不固定,我们可以随意向切片中追加元素,而切片会在容量不足时自动扩容。 cmd/compile/internal/types.NewSlice // NewSlice returns the slice Type with element type elem. func NewSlice(elem *Type) *Type { //返回的结构体 TSLICE 中的 Extra 字段是一个只包含切片内元素类型的 Slice{Elem: elem} 结构, // 也就是说切片原创 2020-11-16 17:45:11 · 139 阅读 · 0 评论 -
bigCache 源码分析
BigCache type BigCache struct { shards []*cacheShard //分片 lifeWindow uint64 //过期时间 clock clock //时间获取的方法 hash Hasher //hash算法 config Config //配置文件 shardMask uint64 //常量:分片数-1,用于&运算替换取模运算 maxShardSize ui原创 2020-11-16 17:42:50 · 455 阅读 · 0 评论