这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。
1.协程(goroutine)
1.1 介绍
- Go 主线程(亦可称为线程):在一个Go线程上,可以起多个协程。可以这样理解,协程是轻量级的线程【编译器做优化】。
- Go协程的特点
- 有独立的栈空间;
- 共享程序堆空间;
- 调度由用户控制;
- 协程是轻量级的线程。
1.2 协程的开启
假设有一函数fun(s),通过go fun(s) 开启一个协程。开启后,以并发的方式运行协程。
1.3 注意事项
- 如果主线程退出了,则协程即使还没有执行完毕,也会退出;
- 当然协程也可以在主线程没有退出前,就自己结束了,比如完成了自己的任务;
- 如果代码设计不当,只使用协程,可能会出现死锁问题,这时需要定义一个全局的互斥锁来管理同步。即:
-
var lock sync.Mutex lock.Lock() 加锁 lock.Unlock() 解锁
-
2. 管道(channel)
2.1 介绍
- channel本质就是一个数据结构-队列;
- 数据是先进先出【FIFO: first in first out】;
- 线程安全,多goroutine访问,不需要加锁,就是说channel本身就是线程安全的;
- 一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值消息,每个channel都有一个特殊的类型。如一个可以发送int类型数据的channel,一般写为chan int。
2.2 使用
-
定义/声明 channel
- 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