这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
知识点总结
并发和并行的区别
- 并发:并发是
轮流处理多个任务- 任务例1:从MySQL中读取数据theme: awesome-green
- 任务例2:向MySQL中写入数据
- 并发过程:先读或者先写,存在一个
先后顺序
- 并行:并行是同时处理多个任务
- 任务例1:从MySQL中读取数据
- 任务例2:向MySQL中写入数据
- 并行过程:读写
同步进行,不存在顺序,两个任务齐头并进
协程和线程的区别
- 协程:用户态,轻量级,堆栈
KB级别 - 线程:内核态,重量级,堆栈
MB级别
通信原理
-
Go提倡通过
通信来共享内存- goroutine1 -> channel -> goroutine2
- channel 负责消息的收发实现通过通信来共享内存
-
Go不提倡但保留了通过
共享内存实现通信的机制- goroutine1 -> 临界区申请互斥量 -> goroutine2
- 通过这种方式需要上锁解锁,性能方面会有所降低
channel的种类
- 无缓冲channel:
- 同步性:阻塞等待到发送者和接收者
都准备就绪才可以使用
- 同步性:阻塞等待到发送者和接收者
- 有缓冲channel:
- 异步性:消息存放在缓冲区,缓冲区满了即阻塞,直到有
发送方->接收方/生产者->消费者从缓冲区取走数据,才能解除阻塞
- 异步性:消息存放在缓冲区,缓冲区满了即阻塞,直到有
sync package
提供了一系列处理并发安全操作,解决协程间的同步问题的工具
- sync.Mutex 互斥锁
- sync.RWMutex 读写锁
- sync.WaitGroup 等待组 底层通过维护一个计数器实现等待一组 goroutine完成的功能
- Add( ) 计数器增加计数 +1
- Done( )计数器完成计数 -1
- Wait( )阻塞直到计数器归0
依赖管理演进
GOPATH
- 缺陷:存在无法实现package的多版本控制的问题
- 缺陷例子:
- 项目A 依赖于 package v1
- 项目B 依赖于 package v2
- 项目A和B 依赖于 同一个package的不同版本
- package v1 => v2 升级导致依赖的失效
Go Vendor
- 解决的问题:
- 通过在每个项目中引入vendor从而解决了多个项目依赖于同一个package的不同版本的问题
- 原理:
- 项目依赖包放在vendor中,由vendor指向GOPATH
- 缺陷:
- 无法控制依赖的版本,包与包之间存在不兼容性
- 缺陷例子:
- package1 依赖于 package3 v1
- package2 依赖于 package3 v2
- 项目A 依赖于 package1 和 package2
- package3 v1 => v2 时项目A会出现依赖冲突
Go Module
- 依赖管理三要素:
- 配置文件-go.mod
- 中心仓库管理依赖库-proxy
- 本地工具-go get/go mod
- indirect标识:
- 存在A->B->C
- 则 A->B直接依赖
- 则 A->C间接依赖
- go.mod中若缺少直接依赖会标识indirect
- incompatible标识:
- 缺少go.mod文件并且依赖主版本在v2以上则会标识incompatible