Go协程
概念
- Go的协程被命名为Goroutine。
- 一个进程拥有多个线程,一个线程拥有多个协程。
- 协程正常运行,但所有返回值会被系统自动忽略,主程序继续执行自己的代码段。
- main.go是一个主的Goroutine,当主Goroutine终止,所有子Goroutine都会被终止。
go关键字
- GO语言通过
go
关键字开启子协程。
func main(){
go fun1()
//主函数代码段
}
func fun1(){
//代码段
}
协程执行的先后顺序
- 遵循,谁先抢到资源谁先执行。
- 可以通过时间睡眠的方式来进行排序执行。
栈溢出及恐慌
- 在32位操作系统中每个Goroutine栈空间最大为250MB,而64位最大为1GB,如果栈空间大于限制,则会引发一个栈溢出(stack overflow)的运行时恐慌。随后,这个GO程序也会终止。
- 此后,主Goroutine会进行一系列初始化工作:
- 创造特殊的defer语句,用于主Goroutine退出的善后工作。
- 启动专用于在后台清扫垃圾的Goroutine,并设置GC可用标志。
- 执行main包中的init()
- 重新执行main()
- 检查主Goroutine是否引发恐慌,并进行必要的处理。
- 主Goroutine关闭自己以及当前进程的运行。
临界资源
- 即多个Goroutine共同拥有的资源,比如变量。
- Go语言理论上不鼓励这种操作
寄语:不要以共享内存来通讯,而是要通过通讯来实现内存共享。
- 这种情况在并发时容易导致错误
- **解决方式:**sync同步包
通道 Channel
概念
- 实现多个Goroutine之间通讯的管道,并来实现多个Goroutine之间传递数据。
- 可以认为,通道就是开辟一个新地址,传递方式就是将值交给地址,在将地址的值交给另一变量。
- 区别在于它在发送数据和接受数据时都是阻塞的,从而实现Goroutine等待。
操作
- 创建通道
// 声明方式创建
var 通道名 chan 它能传递数据的类型
// make方法创建
通道名 := make(chan 数据类型)
- 如何使用通道
// 将通道的值取出给变量
data := <-chan
data,err := <- chan
// 将值赋值给通道
chan <- data
// 关闭通道
colse(chan)
缓冲通道
- 概念:你可以将其看成队列,先进先出
- 如何创建
通道名 := make(chan 数据类型 容量)
定向数据
- 定向通道:只能读或只能写的通道
- 如何创建
//只能读
通道名 := make(chan <- 数据类型 容量)
//只能写
通道名 := make(<- chan 数据类型 容量)
- 应用场景
//创建一个双向通道的数据
ch111 := make(chan int)
//申明函数只能写而不能读,用于保护通道
func 方法名(ch111 chan <- int){
}
GoCSP模型
概念
- GoCSP模型(Communicating Sequential Process)中文解析是通讯顺序进程,基本就是大家认为的并行开发神器。
- Go语言最大的特色有两个,一个是Goroutine,一个是Channel;而二者结合起来就是CSP模型。
- 实体通过使用Channel发送消息来通讯,而它的关键是关注Channel,而不关注发送消息的实体。