Go进阶 | 青训营笔记

59 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第2天。

一、并发编程与依赖管理

协程与线程

解决并发问题,我们常用线程来并行地运行多个程序,但这种内核态的解决方案会占用mb级别的内存调用。轻量级的协程仅占用kb级别的内存,在一个线程中,可以调度多个协程。

Goroutine

Goroutine是Go语言提供的协程,与kotlin中的无栈协程不同,是一种有栈协程。如下代码是一个简单的goroutine的使用例子:


package main

import (
   "fmt"
   "time"
)

func print(i int) {
   fmt.Println(i)
}

func main() {
   for i := 1; i <= 10; i++ {
      go func(j int) {
         print(j)
      }(i)
   }
   time.Sleep(time.Second)
}



其输出结果为:

1
2
6
4
8
5
7
9
3

如果删去 time.Sleep(time.Second)程序将不会有任何输出。原因是当主协程退出后,其中的子协程会立即结束。由于变量的自增执行速度快于打印数字,当main协程结束时,子协程还没来得及打印就被结束了。我们用time.Sleep(time.Second)方法来延迟主协程的结束,这种方法存在一个问题:人为的设定时间并不一定与协程执行时间匹配,可能出现子协程执行完毕,主协程仍然无法结束的问题。Go语言提供了更科学的解决方案:Waitgroup。简单来说waitgroup维护着一个计数器,程序员们可以通过调用Add()方法设定初始值,Done()方法来使计数器-1,wait()方法来使协程阻塞直至计数器为0。这样,我们就能较好的解决主/子协程运行时间不匹配的问题了。

依赖管理

经过不断更迭,go的依赖管理从GOPATH,GoVender,演化为如今的GoModule。GoModule较好地解决了前身的不同项目依赖的同一项目的不同版本问题。Gomodule会评估不同项目的依赖,并且选择能够兼容这些项目的最低版本作为依赖。

小结

今天对go语言的特点,乃至项目方面的依赖管理有了一定的了解。初次接触这些,感觉猪脑有点过载了~