进程与依赖管理 | 青训营笔记

74 阅读3分钟

进程

并发编程

  • 并发与并行 image.png go语言能充分发挥多核cpu的优势以高效运行
  • 协程与线程

image.png - 线程:内核态,栈Kb级别

    是比较昂贵的系统资源,且比较消耗资源,创建切换停止都属于很重的系统操作

-   协程:用户态,轻量级线程,栈Mb级别

    创建和调度有go语言本身去完成,一个线程可以并发的跑多个协程

协程

  • 使用

    调用函数时在函数前加“go”关键字,即可为此函数创建一个协程来运行

    func main() {
        for i := 0; i < 5; i++ {
            go output(i)
        }
        time.Sleep(time.Second)
    }
    func output(a int) {
        fmt.Printf(a)
    }
    
    >>12034
    

    由结果我们可以看出是多协程并行

  • 协程间的通信

    go语言提倡通过通信实现共享内存,而不是共享内存实现通信

    image.png

    优势:通道将协程进行连接,遵循先入先出,能保证收发数据的顺序

    (go也可以通过共享内存实现通信)

通道(Channel)

一种引用类型,需要用make关键字创建

image.png

无缓冲通道会使两个协程同步化,所以无缓冲通道也被称为同步通道

有缓冲通道代表通道中能存放多少元素,满了就会阻塞通道直到被取出

例:

func main() {
    chan1 := make(chan int)
    chan2 := make(chan int, 3)
    go func() {                         //第一个协程
        defer close(chan1)
        for i := 0; i < 10; i++ {
            chan1 <- i                  //将数字传进无缓冲通道
        }
    }()
    go func() {                         //第二个协程
        defer close(chan2)
        for i := range chan1 {          //将数字从无缓冲通道中取出
            chan2 <- i * i              //将数字的平方传入有缓冲通道
        }
    }()
    for i := range chan2 {fmt.Print(i, " ")}//将数字从有缓冲通道中取出并输出
}
>>0 1 4 9 16 25 36 49 64 81 

可以看出,输出是按顺序的,也就是说是线程安全的

Sync

  • WaitGroup

用WaitGroup来进行协程同步的优化

image.png

开启携程后用Add(),在每个协程完成后用Done()方法使计数器减1,通过Wait()进行阻塞

依赖管理

  • 迭代过程 image.png

GOPATH

image.png

  • 原理:用go get直接将最新版本的包下载到src目录中,项目直接依赖src里面导的包
  • 弊端:本地两个项目依赖不同版本的同个包时就可能会寄

Go Vendor

  • 原理:

    • 在项目目录中增加Vendor文件,所有依赖包的副本存在其中
    • 依赖先去找Vendor,找不到就去找GOPATH
  • 优点:解决了GOPATH的弊端

  • 弊端:若项目同时依赖了B和C包,且B和C分别依赖A包的两个版本,就寄了

Go Module (类似于java的Maven)

  • 1.11版本引入,默认打开

  • 优点:可以定义版本规则和管理项目依赖的关系

  • 使用:通过go.mod文件管理依赖包版本,通过go get/go mod 指令工具管理依赖包

  • 依赖管理:

    • 用于描述依赖的配置文件:go.mod
    • 中心仓库管理依赖库:Proxy
    • 本地工具:go get与go mod
  • go.mod

    image.png

  • 依赖配置

    image.png

    • 伪版本:

版本 - 提交某次commit时间戳 - 哈希码前缀

每次提交commit都会生成一个伪版本号

  • 依赖图

image.png 当1.3和1.4相互兼容时,自动选择能够满足本次构建最低兼容版本

  • 依赖分发

    依赖如何下载、去哪里下载的问题

    • 直接依赖软件托管平台(github

      • 无法保证构建稳定性:增删改软件版本
      • 无法保证依赖可用性:删除软件
      • 增加第三方压力:代码托管平台会有负载问题
    • Proxy image.png

      加一层Proxy层解决直接依赖代码托管平台的问题(适配器模式)

    • GOPROXY image.png

      如上例子,查找路径,根据配置,在Proxy1中查找,失败则下放到Proxy2,再失败则直接在代码托管平台下载

    • 工具

      • go get

        image.png

      • go mod(常用)

        image.png