Go语言的进阶和依赖管理
1.并发&并行(Go语言就行用并发)
(1)并发:多线程程序在一个核的cpu上运行
(1)并行:多线程程序在多个核的cpu上运行
2.线程&协程
(1)协程:用户态,轻量级线程,栈KB级别
(2)线程:内核态,线程跑多个协程,栈MB计别
例题:
func hello(i int){
println("hello goroutine:"+fmt.Sprint(i))
}
func HelloGoRoutine(){
for i:=0;i<10;i++{
go func (i int) {
hello(i)
}(i)
}
time.Sleep(time.Second)
}
在调用某个函数是,在前面加“go”关键字,就可以创建协程来运行,实现“快速”运行某个函数,例如上述代码中的go func (i int)。上述代码中的time.Sleep(time.Second)主要是为了保证在子协程未完成之前主协程不会退出
3.协程之间的通信——CSP(Communicating Sequential Processes)
Go语言提倡通过通信共享内存而不是通过共享内存实现通信
4.Channel类型
例如下列代码: func CslSquare(){ 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{ //复杂操作 fmt.Println(i) }
}
A子协程发送0~9数字,B子协程计算输出数字的平方,主协程输出最后的平方数。上述代码在定义dest通道是,运用的是带缓冲的channel,可以解决消费者和生产者之间“速度”不同的问题。
5.并发安全Lock lock.Lock()和lock.Unlock()相当于“加锁”和“解锁”,提高了安全性,提高并发安全,减少共享内存出错的问题。
(1)计数器:开启协程+1,执行结束-1,主协程阻塞直到计数器为0。
6.依赖管理
(一)分类
(1)GOPATH
简单介绍:
环境变量GOPATH一共包含三部分,分别是:bin、pkg和src。其中,bin是项目编译的二进制文件,pkg是项目编译的中间产物,src是项目源码。项目代码直接以来src下的代码,通过go get下载最新版本的包导src目录下。
弊端:
无法实现package多版本的控制
(2)Go Vendor
项目目录增加vendor文件,所有依赖包副本形式放在¥ProjectRoot/vendor
依赖寻址方式:vendor=>GOPATH
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题
弊端:
无法控制依赖的版本,更新项目可能出现依赖冲突导致编译出错。
(3)Go Module
通过go.mod文件管理依赖包版本,通过go get/go mod指令工具管理依赖包
最终目标:定义版本规则和关联项目依赖的关系。
(二)三要素
(1)配置文件,描述依赖 go.mod(依赖管理基本单元、原生库、单元依赖)
(2)中心仓库管理依赖库 Proxy
(3)本地工具 go get/mod
(三)依赖配置
(1)version
语义化版本,基于commit伪版本(版本前缀-时间戳-提交commit的12为的哈希码前缀)
(2)indirect
(3)incompatible
(四)依赖图(选择最低的兼容版本)
(五)依赖分发——回源
直接依赖面临的问题:——解决方式:Proxy
(1)无法保证构建稳定性
(2)无法保证依赖的可用性
(3)增加第三方的压力