Go语言进阶与依赖管理笔记 | 青训营

82 阅读3分钟

1、语言进阶

1.并发与并行

并发并行
处理任务一个CPU处理器同时处理多个线程任务多个CPU处理器同时处理多个线程任务
存在在一个CPU处理器和多个CPU处理器系统中都存在只能在多个CPU处理器系统存在
CPU资源线程之间去抢占CPU资源,轮流使用(时间片)线程间不会抢占CPU资源(各做各)

2.线程与协程

线程从属于进程,是轻量级的进程,处于内核态;协程是一种轻量级线程,从属于线程,处于用户态,即意味着协程的调度完全由用户控制。在Go语言中用的就是协程,这也是Go语言更高效的原因之一。

3.协程间通信

Go语言中提倡通过通信共享内存,而不是通过共享内存实现通信。
Go语言中通道的建立:

   chanA := make(chan int)//无缓冲通道
   chanB := make(chan int, 3)//有缓冲通道,缓冲区大小为3

4.并发安全锁

Go语言中的互斥锁,位于sync包中的Mutex类型。保证同一时间只有一个协程进入临界区,其他的协程则在等待锁;当互斥锁释放后,等待的协程才可以获取锁进入临界区,多个协程同时等待一个锁时,唤醒的策略是随机的。

var lock sync.Mutex
var x int64
func add(){
    for  i := 0; i < 2000; i++ {
        lock.Lock()//获取锁
        x++
        lock.Unlock()//释放锁
    }
}

当只需要读取一个资源而不涉及资源修改的时候,更推荐读写互斥锁。读写锁在Go语言中使用sync包中的RWMutex类型。
读写锁分为两种:读锁和写锁。当一个协程获取读锁之后,其他的协程如果获取读锁则会继续获取锁,如果是获取写锁就会等待;当一个协程获取写锁之后,其他的协程无论是读锁还是写锁都会等待。

var x int64
var rwlock sync.RWMutex
 
func write() {
	rwlock.Lock() //加写锁
	x++
	time.Sleep(time.Microsecond * 10)
	rwlock.Unlock() //解写锁
}
 
func read() {
	rwlock.RLock() //加读锁
	time.Sleep(time.Millisecond)
	rwlock.RUnlock() //解读锁
}

5.WaitGroup

Go语言使用sync.WaitGroup来实现并发同步。主要有三个方法:

  • wg.Add() 计数器+1;
  • wg.Done() 计数器-1;
  • wg.Wait() 等到直到计数器变为0;

sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。当启动了N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用Done()方法将计数器减1。通过调用Wait()来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成。

var wg sync.WaitGroup
 
func hello() {
	defer wg.Done() //输出Hello Goroutine后计数器-1
	fmt.Println("Hello Goroutine!")
}
func main() {
	wg.Add(1) //计数器+1
	go hello() // 启动另外一个goroutine去执行hello函数
	fmt.Println("main goroutine done!")
	wg.Wait() //等到计数器为0
}

2、依赖管理

1.Go依赖管理演进历程:GOPATH -> Go Vendor -> Go Module

  • GOPATH的管理模式下,如果多个项目依赖同一个库,则依赖该库是同一份代码,所以不同项目不同依赖同一个库的不同版本时,会发生编译错误。
  • Vendor是当前项目中的一个目录,存放当前项目依赖的副本,如果当前项目存在Vendor目录,会优先使用该目录下的依赖,如果依赖不存在,会从GOPATH中找;但仍然无法控制依赖的版本,更新项目又可能出现依赖冲突,导致编译错误。
  • Go Module通过go.mod文件管理依赖包版本,通过go get/go mod指令工具管理依赖包。

2.依赖管理三要素

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

3.go get/mod的一些常用

go get example.org/pkg +下列后缀

  • @update 默认
  • @none 删除依赖
  • @v1.12 tag版本,语义版本
  • @1111ABC 特定的commit
  • @master 分的最新commit

go mod + 下列后缀

  • init 初始化,创建go.mod文件
  • download 下载模块到本地缓存
  • tidy 增加需要的依赖,删除不需要的依赖