这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
简介
Go 语言提倡通过通信共享内存, 而不是通过共享内存实现通信。 这两种方式之间有巨大的区别。
Go 语言保留通过共享内存实现通信,必须通过互斥量对内存加锁, 获取临界区的权限。 这种方法容易发生数据竞赛的问题。会影响性能。
由于 Go 本身更推荐前面一种形式,同时它也是 Go 相对其它语言的主要特点之一, 本篇文章只讨论前面的一种形式。
Goroutine
线程与协程的区别
线程和协程有三个主要的区别, 分别是运行级别不同,代价花费不同,栈空间不同, 如下图所示。
| | 运行级别 | 代价花费 | 栈空间 | | 线程 | 内核态 | 含多个协程 | KB 级别 | | 协程 | 用户态 | 轻量级线程 | MB 级别 |
由于 一般情况下,线程数量较少,而协程
总结
它其实并不完全由用户控制。
从性能上讲,线程的创建、切换、都是花费非常多系统资源的操作, 同时操作系统的栈内存大小一般是固定值,这会使得栈空间比较浪费, 而协程的栈空间就非常灵活了,其声明周期开始时只有一个很小的栈。 从开发上讲,通过线程实现并发编程时,我们需要自己维护线程池, 同时管理任务的调度维护上下文的切换, Goroutine 是协程的 Go 语言实现,创建和调度由 Go 语言本身去完成, 这使得开发方便许多。
Channel
make(chan <元素类型>, <缓冲大小>)
缓冲大小为元素个数,可以不填入,通道可以因此分为两个类型。
- 无缓冲通道,由于接收后立即发送,也称同步通道
- 有缓冲通道,当容量慢时会阻塞发送,直到其中内容被取走