Go进阶之并发与依赖管理 | 青训营笔记

77 阅读2分钟

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

知识点总结

并发和并行的区别

  • 并发:并发是轮流处理多个任务
    • 任务例1:从MySQL中读取数据theme: awesome-green
    • 任务例2:向MySQL中写入数据
    • 并发过程:先读或者先写,存在一个先后顺序
  • 并行:并行是同时处理多个任务
    • 任务例1:从MySQL中读取数据
    • 任务例2:向MySQL中写入数据
    • 并行过程:读写同步进行,不存在顺序,两个任务齐头并进

协程和线程的区别

  • 协程:用户态,轻量级,堆栈KB级别
  • 线程:内核态,重量级,堆栈MB级别

通信原理

  • Go提倡通过通信来共享内存

    • goroutine1 -> channel -> goroutine2
    • channel 负责消息的收发实现通过通信来共享内存
  • Go不提倡但保留了通过共享内存实现通信的机制

    • goroutine1 -> 临界区申请互斥量 -> goroutine2
    • 通过这种方式需要上锁解锁,性能方面会有所降低

channel的种类

  • 无缓冲channel:
    • 同步性:阻塞等待到发送者和接收者都准备就绪才可以使用
  • 有缓冲channel:
    • 异步性:消息存放在缓冲区,缓冲区满了即阻塞,直到有发送方->接收方/生产者->消费者从缓冲区取走数据,才能解除阻塞

sync package

提供了一系列处理并发安全操作,解决协程间的同步问题的工具

  • sync.Mutex 互斥锁
  • sync.RWMutex 读写锁
  • sync.WaitGroup 等待组   底层通过维护一个计数器实现等待一组 goroutine完成的功能
    • Add( ) 计数器增加计数 +1
    • Done( )计数器完成计数 -1
    • Wait( )阻塞直到计数器归0

依赖管理演进

GOPATH

  • 缺陷:存在无法实现package的多版本控制的问题
  • 缺陷例子:
    • 项目A 依赖于 package v1
    • 项目B 依赖于 package v2
    • 项目A和B 依赖于 同一个package的不同版本
    • package v1 => v2 升级导致依赖的失效

Go Vendor

  • 解决的问题:
    • 通过在每个项目中引入vendor从而解决了多个项目依赖于同一个package的不同版本的问题
  • 原理:
    • 项目依赖包放在vendor中,由vendor指向GOPATH
  • 缺陷:
    • 无法控制依赖的版本,包与包之间存在不兼容性
  • 缺陷例子:
    • package1 依赖于 package3 v1
    • package2 依赖于 package3 v2
    • 项目A 依赖于 package1 和 package2
    • package3 v1 => v2 时项目A会出现依赖冲突

Go Module

  • 依赖管理三要素:
    • 配置文件-go.mod
    • 中心仓库管理依赖库-proxy
    • 本地工具-go get/go mod
  • indirect标识:
    • 存在A->B->C
    • 则 A->B直接依赖
    • 则 A->C间接依赖
    • go.mod中若缺少直接依赖会标识indirect
  • incompatible标识:
    • 缺少go.mod文件并且依赖主版本在v2以上则会标识incompatible