- Go语言的并发、依赖管理
- 1.并发与并行
- 并发:多线程程序在一个核的cpu上运行
- 并行:多线程程序在多规格核的cpu上运行
- Go语言可以发挥多核的优势,高效运行
- - 1.1Goroutine
- 协程:用户态,轻量线程,栈kb级别
- 线程:内核态,线程跑多个协程,栈mb级别
- hello word快速打印
- wait是用作阻塞
package main
import (
"fmt"
"sync"
)
func hello(i int) {
println("hello world : " + fmt.Sprint(i))
}
func ManyGo() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(j int) {
defer wg.Done()
hello(j)
}(i)
}
wg.Wait()
}
func main() {
ManyGo()
- }
- 1.2csp(Communicating Sequential Processes
- 协程之间通过通信而共享内存,之间用到通道,通道将Goroutine之间连接,像队列一样,先进先出,
- 提倡通过通信共享内存而不是通过共享内存而实现通信
- 1.3
- Channel
- 通道分为有缓冲通道和无缓冲通道
- 函数代码
make(chan 元素类型,[缓冲大小])无缓冲通道 make(chan int)有缓冲通道 makk(chan int 2)- Channel
- A子协程发送0~9的数字
src := make(chan int)
dest := make(chan int, 3)
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}
B协程计算出输入数字的平方
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
主协程输出
for i := range dest {
println(i)
}
- 1.4lock并发安全的问题
- 通过临界区控制的枷锁加锁
func addwithlock() {
for i :=0;i<200;i++ {
lock.lock(){
x=x+1;
lock.unlock()
}
}
并发安全问题,如果不加锁,而会出现未知错误 WaitGroup 实现堵塞的一种方法,标准函数库提供的一种并发原语,Go语言提供了三种方法
Add方法用于设置 WaitGroup 的计数值,可以理解为子任务的数量Done方法用于将 WaitGroup 的计数值减一,可以理解为完成一个子任务Wait方法用于阻塞调用者,直到 WaitGroup 的计数值为0,即所有子任务都完成- - 2.依赖管理
- GOPATH
- 环境变量¥GOPATH
- 分为三个目录
- bin 项目编译的二进制文件
- pkg 项目编译的中间产物,加速编译
- src 项目源码
- 项目代码直接依赖src下的代码
- go get 下载最新版本的包到src目录下
- 2.1.1GOPATH-弊端
- 如果两种场景ab 依赖与-package不同版本
- 问题则无法实现package的多版本的控制
- GO Vendor
- 项目目录下增加vendor文件,所有依赖包副本形式放在¥ProjectRooot/vendor
- 依赖寻址方式vendor=>GOPATH
- 通过每个项目引入一份依赖的副本,解决多个项目需要同一个package依赖的冲突问题
- 2.1.2 GO Vendor-弊端
- 无法控制依赖的版本
- 更新项目于有可能出现的以来的冲突,导致编译出错
- 2.1.3Go Module
- 通过go.mod文件管理依赖包的版本
- 通过go get/go mod指令 工具管理依赖包
- 终极目标:定义版本规则和管理项目依赖关系
- 2.2依赖管理的三要素
- 1.配置文件,描述依赖, go.mod
- 中心仓库管理依赖库 Proxy
- 3.本地工具 go get/ mod