这是我参与「第五届青训营 」笔记创作活动的第2天
1.本堂课重点内容
- 从并发编程了解Go高性能的本质
- 了解go语言的依赖管理
2.具体案例
- 协程的使用,快速打印hello goroutine
- Channel的具体使用
3.Go高性能的本质
3.1 并发
多线程程序在一个核的cpu上运行 通过时间片的切换,实现同时运行的状态
3.2 并行
多线程程序在多个核的cpu上运行
3.3 Goroutine
3.3.1 线程与协程
线程是系统比较昂贵的系统资源,操作是系统操作。
协程是轻量级的线程,操作是程序员操作
- 协程:用户态,轻量级线程,栈KB级别
- 线程:内核态,线程可以跑多个协程,栈MB级别
3.3.2 协程的使用
go语言调用协程非常简单,只需要在要调用的方法前加go关键字
注意:如果不加阻塞,子协程在执行完成前,主线程可能已经退出,导致运行框无结果。
func name(){
语句
}
func main(){
go func(){
name()
}()
阻塞
}
课程实例
func hello(i int) {
fmt.Println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine() {
for i := 0; i < 5; i++ {
go func(j int) { // 使用协程
hello(j)
}(i) //传入的参数
}
time.Sleep(time.Second) //阻塞
}
3.4 协程间的通信(CSP)
3.4.1 通信共享内存与共享内存实现通信
提倡通过通信共享内存,而不是通过共享内存实现通信
主要使用通道channel 遵循先入先出
通过一个协程发送信息到其他协程
影响程序的性能
3.4.2 Channel
Channel类型的定义
//无缓冲通道
make(chan 元素类型)
//有缓冲通道
make(chan 元素类型, [缓冲大小])
有缓冲与无缓冲的区别
- 无缓冲会使接收的goroutine与发送的goroutine同步化简称同步通道
- 有缓冲通道解决同步问题
Channel的具体使用
//无缓冲
src := make(chan int)
//有缓冲
dest := make(chan int, 3)
go func() {
//协程执行完毕后关闭通道
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
//协程执行完毕后关闭通道
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
println(i)
}
3.5 并发安全Lock
使用锁机制保证并发安全
lock.Lock() 加锁
lock.Unlock() 释放
eg:
var (
x int64
lock sync.Mutex
)
func addWithLock() {
for i := 0; i < 2000; i++ {
lock.Lock()
x += 1
lock.Unlock()
}
}
func addWithoutLock() {
for i := 0; i < 2000; i++ {
x += 1
}
}
func main() {
x = 0
for i := 0; i < 5; i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("WithLock:", x)
x = 0
for i := 0; i < 5; i++ {
go addWithoutLock()
}
time.Sleep(time.Second)
println("WithoutLock:", x)
}
3.6 WaitGroup
等于是一个计数器,每开启一个协程就加一,协程执行完毕后减一,可以使用Wait方法阻塞直到所有的协程停止
var wg sync.WaitGroup //WaitGroup声名
wg.Add(协程数量)
wg.Done() //协程关闭后减一
wg.Wait() //阻塞直到所有的协程关闭
4. go语言的依赖管理
4.1 背景
- 工程项目不可能基于标准库0~1编码搭建
- 管理依赖库
4.2 依赖管理演进
- GOPATH
环境变量 $GOPATH
项目代码直接依赖src下的代码
go get 下载到src下
弊端
无法实现package的多版本控制 - Go Vendor
依赖寻址方式:vendor => GOPATH
弊端
依赖冲突 - Go Module
通过go.mod文件管理依赖包版本
通过go get/mod 指令管理依赖包
4.3 依赖管理三要素
- 配置文件,描述依赖
- 中心仓库管理依赖库
- 本地工具