笔记标题 | 青训营笔记

132 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。

1.协程(goroutine)

1.1 介绍

  1. Go 主线程(亦可称为线程):在一个Go线程上,可以起多个协程。可以这样理解,协程是轻量级的线程【编译器做优化】。
  2. Go协程的特点
  • 有独立的栈空间;
  • 共享程序堆空间;
  • 调度由用户控制;
  • 协程是轻量级的线程。

1.2 协程的开启

假设有一函数fun(s),通过go fun(s) 开启一个协程。开启后,以并发的方式运行协程。

1.3 注意事项

  1. 如果主线程退出了,则协程即使还没有执行完毕,也会退出;
  2. 当然协程也可以在主线程没有退出前,就自己结束了,比如完成了自己的任务;
  3. 如果代码设计不当,只使用协程,可能会出现死锁问题,这时需要定义一个全局的互斥锁来管理同步。即:
    • var lock sync.Mutex
        lock.Lock() 加锁
        lock.Unlock() 解锁
      

2. 管道(channel)

2.1 介绍

  1. channel本质就是一个数据结构-队列;
  2. 数据是先进先出【FIFO: first in first out】;
  3. 线程安全,多goroutine访问,不需要加锁,就是说channel本身就是线程安全的;
  4. 一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值消息,每个channel都有一个特殊的类型。如一个可以发送int类型数据的channel,一般写为chan int。

2.2 使用

  • 定义/声明 channel

    1. var 变量名 chan 数据类型
  • 举例:
      var intChan chan int (intChan 用于存放int数据)
      var mapChan chan map[int]string (mapChan用于存放map[int]string类型)
      var perChan chan Person (perChan 用于存放Person 结构体类型)
      var perChan1 chan Person (perChan1 用于存放Person 指针结构体类型
    

    2. 说明 - channel是引用类型 - channel必须初始化才能写入数据,即make后才能使用 - 管道在不使用时,需要关闭。当管道关闭后,读取数据是可以的,但不能再往管道写入数据了。 3. 写入读出数据

    • 举例:
  •       var intChan chan int
          intChan = make(chan int,3)   //初始化
          
          //向管道写入数据
          intChan <- 10
          num:=20
          intChan <- 50
          
          //向管道读取数据
          num1:=<- intChan
          num2:=<- intChan