并发编程
- 并发&并行的区别:并发指的是多线程程序在单核cpu上运行,而并行指的是多线程程序在多核cpu上运行,可以理解成并行是实现并发的一种手段
- 协程:用户态的轻量级线程,栈是KB级别
- 线程:内核态的重量级线程,一个线程跑多个协程(可能上万个协程),栈是MB级别
- GO语言中开启线程的方法:go关键字 go后面加上要跑多线程的函数,跑出来的线程结果其实是乱序输出的,类似Java中的thread
- CSP(Communicating Sequential Processes):提倡通过通信共享内存而不是通过共享内存实现通信,用通过共享内存实现通信的方法会导致不同的route之间的数据静态的问题,会影响程序的运行效率
- Channel:通过make关键字创建,可以创建两种channel,一种有缓冲通道,一种无缓冲通道。使用无缓冲通道进行通信时,发送的gorountine和接收的gorountine是同步的,所以无缓冲通道也被称为同步通道;使用带有缓冲区的channel时可以实现异步通信。将生产出来的数据传输到channel中要用 <- 字符;用range关键字来遍历channel
- 并发安全lock:跟Java的synchronization类似,用于锁定某一段代码的权限使其能够依次完整的执行完每个线程再将权限开放给下一个线程执行,不加锁可能会导致undefined behavior,而加锁后更好的规范了代码的运行逻辑
- WaitGroup:这一块跟C语言的child process类似,都是利用wait函数来reap执行完了的child process,保证parent process会等到所有的child process都被reap之后才会种植,防止zombie process的出现
依赖管理
- 不同环境依赖的盘本不同,我们需要控制和管理依赖库的版本
- GOPATH:项目代码直接依赖于src下的代码,go get下载最新版本的package到src目录上。弊端:无法实现package的多版本控制
- Go Vender:在项目录下增加一个vender的文件夹,文件夹中通过每个项目引入一个依赖的副本,解决了多个项目需要同一个package依赖的问题。弊端:vender不区分package的版本,会在版本选择上出现问题,出现依赖冲突导致编译错误;主要依赖的还是源码,没有办法区分版本
- Go Module:最新版本,通过go.mod管理依赖包版本,可以通过指令工具管理依赖包
- 依赖管理三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
- 依赖配置:indirect(A->B->C 关系:A->B直接依赖 A->C间接依赖)
- 依赖配置:incompatible 编译时会选择最低的兼容版本