Go语言进阶与依赖管理
1语言进阶
1.1Goroutine
Go可以充分发挥多核优势,运行高效
再调用一个函数时候在前面加上“go”就为这个函数创建了一个协程 用time.Sleep(time.Second)来保证子协程执行完之前主协程不退出,用在每一个子协程的后面 代码示例
func hello(i int){
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)
}
1.2CSP(Communicating Sequential Processes)
Go提倡通过通信共享内存
Go也保留右图的机制
1.3Channel 创建: make(chan元素类型,[缓冲大小]) 分类:
- 无缓冲通道(又称同步通道) make(chan int)
- 有缓冲通道 make(chan int,2)
“同步”解释:发送和接收是同步的
“缓冲”工作:通道容量满了之后,必须有rountine取走数据才可以继续往channel内发送数据(典型的生产消费模型)
Channel的具体使用示例:
- A子协程发送0~9数字
- B子协程计算输入数字的平方
- 主协程输出最后的平方数
func CalSquare(){
src:=make(chan int)//A与B之间的channel
dest:=make(chan int,3)//B与主协程之间的channel
go func(){//创建A协程
defer close(src)//???????
for i:=0;i<10;i++{
src<-i//将生成的数字推入A协程
}
}()//?????
go func(){
defer close(dest)
for i:=range src{//B协程从src通道中接受数据
dest<-i*i
}
}()
for i:=range dest{//主协程从dest通道中接收数据并输出
//带缓冲的channel可以解决生产与消费速率不同带来的执行效率问题
//一般来说,消费时是复杂的,更慢
println(i)
}
}
1.4并发安全Lock
示例:对变量进行2000次+1操作,要求5个协程并发执行
package main
import (
"sync"
"time"
)
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 Add() {
x = 0
for i := 0; i < 5; i++ {
go addWithoutLock() //5个协程
}
time.Sleep(time.Second)
println("WithoutLock:", x)
x = 0
for i := 0; i < 5; i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("WithLock:", x)
}
func main() {
Add()
}
1.5WaitGroup
func hello(i int){
Println("hello foroutine :"+fmt.Sprint(i))
}
func HelloGoRoutine(){
for i:=0;i<5;i++{
go func (j int){
hello(j)
}(i)
}
time.Sleep(time.Second)
}
func ManyGoWait(){
var wg sunc.WaitGroup
wg.Add( 5)
for i:=0;i<5;i++{
go func(j int){
defer wg.Done()
hello(j)
}(i)
wg.Wait()
}
}
2依赖管理
背景:
- 依赖:各种开发包
- 工程项目不可能基于标准库从头编码搭建
2.1Go依赖管理
演进:
- GOPATH
- GoVendor
- GoModule
2.1.1GOPATH环境变量
GOPATH是我们的工作目录,其中包含的最主要的三个文件是bin,,pkg,src
- bin 项目编译的二进制文件
- pkg 项目编译的中间产物,加速编译
- src 项目源码 项目代码直接以来src下的代码 go get下载最新版本的报道src目录下
GOPATH弊端:无法实现package的多版本控制
2.1.2Go Vender
Go Vender弊端
2.1.3Go Module
2.2依赖管理三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod