Go语言进阶 | 青训营笔记

43 阅读1分钟

Go语言进阶与依赖管理

Go语言进阶

线程 VS 协程

image.png 线程: 内核态,切换需要trap系统调用,比较重的操作,栈MB级

协程: 用户态, go语言支持。栈KB级

例子:

func hello(j int) {
	fmt.Println("hello ", j)
}

func main() {
	// 快速打印hello world
	for i:=0 ; i < 5; i++ {
		go hello(i);
	}
	time.Sleep(1*time.Second)
}

协程间通信

image.png

提倡通过通信共享内存 —— 需要通道(channel)

不提倡通过共享内存通信(临界区)

channel

image.png make(chan type, size)

初始化时有size的就是有缓冲通道,没有的就是无缓冲通道

简单的生产-消费例子:

func CalSquare(){
	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);
	}
}

并发安全 Lock

例子:

var (
	x int64
	lock sync.Mutex
)

func addWithLock(){
	for i := 0; i < 100 ; i++ {
		lock.Lock()
		x+=1
		lock.Unlock()
	}
}

func addWithoutLock(){
	for i := 0; i < 100 ; i++ {
		x+=1
	}
}

WaitGroup

通过waitgroup来实现协程同步

-Add(): 创建协程时调用这个函数,增加wg的值 -Done(): 协程执行完毕时调用这个函数,表示协程退出,减少wg的值 -Wait(): 主线程等待wg的值为0

Go语言依赖管理

GOPATH

  • 所有项目都依赖$GOPATH/src下的包

  • go get的时候,都下载到$GOPATH/src

image.png

问题: 无法实现package的多版本控制

GO Vendor

  • 项目目录下增加vendor文件,所有依赖包以副本的形式放在$ProjectRoot/vendor下
  • 解决多个项目需要同一个package依赖冲突

问题: image.png

Go Mod

  • 通过go.mod管理依赖包版本
  • 通过go get/ go mod指令工具管理依赖包

依赖管理三要素

  1. 配置文件描述依赖 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 go get/mod