Go 工程进阶 | 青训营笔记

51 阅读2分钟

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

掌握

  1. 并发编程

不足

  1. 依赖管理没掌握
  2. 单元测试一直懵

并发模型

Go 语言的并发模型其中一种是 Goroutine,他是Go中最基本的执行单元。事实上每一个Go程序至少有一个Goroutine:主Goroutine。当程序启动时,它会自动创建。

  • 先简单理解一下线程和协程的区别

线程(Thread) :用户态,轻量级线程,栈MB级别。

协程(coroutine) :内核态,线程跑多个协程,栈KB级别

协程和线程类似,共享堆,不共享栈,协程的切换一般由程序员在代码中显式控制。它避免了上下文切换的额外耗费,兼顾了多线程的优点,简化了高并发程序的复杂。

Goroutine和其他语言的协程(coroutine)在使用方式上类似,但从字面意义上来看不同(一个是Goroutine,一个是coroutine),再就是协程是一种协作任务控制机制,在最简单的意义上,协程不是并发的,而Goroutine支持并发的。因此Goroutine可以理解为一种Go语言的协程,同时它可以运行在一个或多个线程上。1. 线程都有一个独立的 ID 号,而 goroutine 却没有。

事实上,Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine。

简单实例:

func loop() {
    for i := 0; i < ; i++ {
        fmt.Printf("%d ", i)
    }
}

func main() {
   go loop() // 启动一个goroutine
    loop()
}

另外,goroutine 调度器使用 GOMAXPROCS 参数来控制会有多少个 OS 的线程同时执行 Go 的代码。

Go 语言的并发模型还有一种,是Go语言特有的,也是Go语言推荐的:CSP(communicating sequential processes)并发模型。Go的CSP并发模型,是通过goroutinechannel来实现的。

  • goroutine 是Go语言中并发的执行单位。有点抽象,其实就是和传统概念上的”线程“类似,可以理解为”线程“。
  • channel是Go语言中各个并发结构体(goroutine)之前的通信机制。 通俗的讲,就是各个 goroutine 之间通信的”管道“,有点类似于Linux中的管道。

生成一个goroutine的方式:Go一下。

go f();

通信机制 channel 也很方便,传数据用 channel <- data ,取数据用 <-channel 。

在通信过程中,传数据 channel <- data 和取数据 <-channel 必然会成对出现,因为这边传,那边取,两个 goroutine 之间才会实现通信。

而且不管传还是取,必阻塞,直到另外的 goroutine 传或者取为止。