Go语言进阶-工程进阶|青训营笔记

62 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天,本次课程主要介绍Go语言进阶知识以及项目相关技术。

本堂课的重点内容为:

  1. 并发编程
  2. 依赖管理
  3. 单元测试
  4. 项目实战

一、并发编程

1.channel

channle 本质就是一个队列,在go语言中叫做管道,使用通信的方法代替共享内存,声明方式如下所示:

src := make(chan int)
dest := make(chan int, 3)

使用make进行创建,可以指定通道的参数类型以及通道的缓存大小。

将一个值发送到channel中的代码如下:src <- 10

从channel中取值的操作为:

x := <- src // 从src中接收值并赋值给变量x
<-src       // 从src中接收值,忽略结果

相比于缓冲通道,无缓冲通道的通信是同步的,即只有在有人接收值的时候才能发送值,适当的设置缓冲区大小能有效减少阻塞的可能和时间。

对于通道,可以使用range进行循环遍历并对通道操作:

go func() {
   defer close(dest)
   for i := range src {
      dest <- i * i
   }
}()

在使用多个协程时,可能会遇到并发的安全问题,可以使用 sync.Mutex设置一个lock锁,进行限制,具体示例如下:

首先创建变量x以及锁lock,类型为sync.Mutex

var(
    x       int64
    lock    sync.Mutex
)

使用lock对临界区进行上锁以及解锁操作:

func addWithLock() {
   for i := 0; i < 2000; i++ {
      lock.Lock()//上锁
      x += 1
      lock.Unlock()//解锁
   }
}

这样在对x进行操作的过程中就能保证并发安全。另外,go语言还提供了WaitGroup用于对协程数量以及是否全部完成的统计。 具体使用如下:

func ManyGoWait() {
   var wg sync.WaitGroup
   wg.Add(5)//设置协程数量
   for i := 0; i < 5; i++ {
      go func(j int) {
         defer wg.Done()//协程结束后会调用Done将数量减一
         hello(j)
      }(i)
   }
   wg.Wait()//当协程数量为0时执行完成
}

以上就是本节课并发编程的内容。