这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
并发编程
并发 VS 并行
- 并发是多线程程序在一个CPU内核上通过不断的去切换时间片去运行
- 并行则是多线程程序在多个CPU内核上同时去分别运行
Goroutine(协程)
对于协程和线程:
- 线程是在内核态启动的,对于线程来说,可以去调动多个协程,线程栈MB级别
- 协程则是在用户态由Golang去调用,协程是很轻量的,可以看成是轻量的线程,栈KB级别
在golang中创建协程是通过go关键字去创建的:
package main
import "fmt"
func hello(i int) {
fmt.Println("hello goroutine: ", i)
}
func main() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
}
在执行协程时,一定要确保子协程全部执行完之后才能结束主协程,否则可能会导致子协程只执行了部分
CSP
在golang中,提倡通过通信来共享内存而不是通过共享内存去实现通信
Channel
make(chan 元素类型 [缓冲大小])
- 有缓冲通道
- 无缓冲通道
在golang中,使用channel的方式通过通信来共享内存
也可以使用共享内存去实现通信,但在这种情况下要使用锁机制,对操作权限进行限制
WaitGroup
因为在并发中,无法确定子协程全部执行完所需要的时间,所以在golang中设置了一个计数器去处理
其是通过在sync.WaitGroup的Add Done Wait方法实现的
Add()统计所有的子协程数,每次执行完一个子协程后,就调用Done()方法将计数器减一,Wait()则是堵塞主协程的执行直到计数器的值为0时,也就是所有的子协程执行完后
依赖管理
需求:
- 不同环境(项目)依赖的版本不同
- 控制依赖库的版本
Go Module
- 配置文件,描述依赖
go.mod - 中心仓库管理依赖库
Proxy - 本地工具
go mod/get