Go进阶-依赖管理与测试 | 青训营笔记

63 阅读2分钟

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

Go语言进阶

并发编程

并发 vs 并行

  • 多线程程序在一个核的cpu上运行---并发
  • 多线程程序在多个核的cpu上运行---并行

go可以由标准库支持天然支撑高并发,可以充分发挥多核优势,高效运行程序。

Goroutine

内核态中分为多个线程,创建和删除一个线程的开销都比较大。而go语言中的协程则属于用户态的部分,可以理解为轻量级线程,创建和删除的开销都比较小。

  • 协程:用户态,轻量级线程,栈KB级别
  • 线程:内核态,线程跑多个协程,栈MB级别

如,多goroutine快速打印。

image.png 由于除了main goroutine以外开了5个goroutine同时进行对i进行打印,得出的结果顺序自然是随机的。其中的一种结果为:

image.png

CSP(Communicating Sequential Processes)

  • 通过通信共享内存
  • 通过共享内存实现通信

通过通信共享内存需要使用channel

Channel

Channel是一种引用类型,使用make关键字来创建,根据是否有缓冲通道可以分为

  • 无缓冲通道 make(chan int)也称为同步通道
  • 有缓冲通道 make(chan int,2)表示有两个缓冲通道的channel,也是一种经典的生产消费模型

如通过两个子协程使用channel发送相关数据,最后由主协程输出最后的结果。

image.png

结果如下

image.png

可以发现使用此例中使用channel来传递数据是可以保证顺序的,也就是说channel的这种使用方式是并发安全的。带缓冲的channel可以解决生产消费中的速度问题

并发安全Lock

此例中分别使用五个协程来计算2000次的x += 1,分别使用有锁的函数和无锁的函数来实现循环累加。具体的代码如图所示:

image.png 预期的结果应该是五个协程各加2000得到最终结果10000.但实际的两个函数的结果不同。

image.png 无锁的函数的运行结果是未知的,也就是并发不安全的问题,而有锁的函数运行结果符合预期,是并发安全的。

未完待续......

依赖管理

测试

项目实战