Golang
背着电脑去搬砖
码龄4年
展开
-
Golang中sync.Map的实现原理
前言前面,我们讲了map的用法以及原理Golang中map的实现原理,但我们知道,map在并发读写的情况下是不安全。需要并发读写时,一般的做法是加锁,但这样性能并不高,Go语言在 1.9 版本中提供了一种效率较高的并发安全的 sync.Map,今天,我们就来讲讲 sync.Map的用法以及原理使用方法func main() { var m sync.Map //插入 m.Store("1","a") //取值 fmt.Println(m.Load("1")) //删除 m.Delete(原创 2020-11-05 14:50:05 · 2720 阅读 · 0 评论 -
Golang中panic与recover的实现原理
今天我们讲讲golang中panic异常,以及recover对异常的捕获,由于panic、recover、defer之间非常亲密,所以今天就放在一起讲解,这里会涉及到一些defer的知识,有兴趣可以看我的另一篇关于defer的文章 Golang中defer的实现原理.Panic异常Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、 空指针引用等。这些运行时错误会引起painc异常。一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟原创 2020-10-24 15:52:20 · 2514 阅读 · 12 评论 -
Golang中context实现原理剖析
转载: Go 并发控制context实现原理剖析1. 前言Golang context是Golang应用开发常用的并发控制技术,它与WaitGroup最大的不同点是context对于派生goroutine有更强的控制力,它可以控制多级的goroutine。context翻译成中文是"上下文",即它可以控制一组呈树状结构的goroutine,每个goroutine拥有相同的上下文。典型的使用场景如下图所示:上图中由于goroutine派生出子goroutine,而子goroutine又继续派生新的转载 2020-09-18 12:02:09 · 2318 阅读 · 1 评论 -
Golang中defer的实现原理
前言在Go语言中,可以使用关键字defer向函数注册退出调用,即主函数退出时,defer后的函数才被调用。defer语句的作用是不管程序是否出现异常,均在函数退出时自动执行相关代码。 所以,defer后面的函数通常又叫做延迟函数defer规则1.延迟函数的参数在defer语句出现时就已经确定下来了func a() { i := 0 defer fmt.Println(i) i++ return}返回结果:defer语句中打印的变量i在defer出现时就已经拷原创 2020-09-14 16:23:49 · 1022 阅读 · 0 评论 -
Golang中select的实现原理
前言select是Golang在语言层面提供的多路IO复用的机制。与switch语句稍微有点相似,也会有case和最后的default选择支。每一个case代表一个通信操作(在某个channel上进行发送或者接收)并且会包含一些语句组成一个语句块。基本用法select会等待case中能够执行的case时才去执行。当满足条件时。select才回去通信并执行case之后的语句,这时候其他通信是不执行的。如果有多个case同时就绪,select会随机选择一个执行。一个没有任何case的select语句,会永原创 2020-08-19 20:30:07 · 1653 阅读 · 3 评论 -
Go 逃逸分析
前言所谓逃逸分析(Escape analysis)是指由编译器决定内存分配的位置,不需要程序员指定。函数中申请一个新的对象如果分配 在栈中,则函数执行结束可自动将内存回收;如果分配在堆中,则函数执行结束可交给GC(垃圾回收)处理;有了逃逸分析,返回函数局部变量将变得可能,除此之外,逃逸分析还跟闭包息息相关,了解哪些场景下对象会逃逸至关重要。逃逸策略每当函数中申请新的对象,编译器会跟据该对象是否被函数外部引用来决定是否逃逸:如果函数外部没有引用,则优先放到栈中;如果函数外部存在引用,则转载 2020-08-13 17:20:49 · 188 阅读 · 0 评论 -
Golang中的goroutine调度
前言在go语言中,每一个并发的执行单元叫做一个goroutine。你可以启动许多甚至成千上万的goroutine,Go的runtime负责对goroutine进行管理。所谓的管理就是“调度”,粗糙地说调度就是决定何时哪个goroutine将获得资源开始执行、哪个goroutine应该停止执行让出资源、哪个goroutine应该被唤醒恢复执行等Goroutine调度器线程数过多,意味着操作系统会不断的切换线程,频繁的上下文切换就成了性能瓶颈。 Go提供一种机制,可以在线程中自己实现调度,上下文切换更轻量原创 2020-07-17 20:20:09 · 907 阅读 · 0 评论 -
Golang中channel的实现原理
前言如果说goroutine是Go语言程序的并发体的话,那么channel则是它们之间的通信机制。一个channel就是一个通讯机制,可以让一个goroutine通过它给另一个goroutine发送值信息。每一个channel都有一个特殊的类型,也就是channel可发送数据的类型。与map类似,channel也对应一个make创建的底层数据结构的引用。当我们复制一个channel或者用于函数参数传递时,我们只是拷贝了一个channel引用,因此调用者和被调用者将引用同一个channel对象。两个相同原创 2020-07-15 17:11:44 · 2105 阅读 · 0 评论 -
Golang中map的实现原理
前言在Go语言中,一个map就是一个哈希表的引用。它是一个无序的key/value对的集合,其中,所有的key都是不同的。然后通过给定的key可以在常数时间复杂度内检索、更新或删除对应的value在map中的元素不是一个变量,因此不能对map的元素进行取址操作。因为map可能随着元素数量的增加而重新分配内存更大的内存空间,从而导致之前的地址失效map实现原理注意:我会把源码中每个方法的作用都注释出来,可以参考注释进行理解。数据结构我们先来看一下map数据结构runtime/map.go/原创 2020-07-11 17:36:46 · 848 阅读 · 0 评论 -
Golang中slice的实现原理
前言简单来说,切片就是一种简化版的动态数组。因为动态数组的长度是不固定,切片的长度自然也就不能是类型的组成部分了。数组虽然有适用它们的地方,但是数组的类型和操作都不够灵活,因此在Go代码中数组使用的并不多。而切片则使用得相当广泛。Slice源码分析注意:我会把源码中每个方法的作用都注释出来,可以参考注释进行理解。在看源码之前,我们先来看一个简单的例子func main() { slice:=make([]int,0) //第6行 slice=append(slice,1)//第7行}原创 2020-07-09 13:47:41 · 1252 阅读 · 0 评论