在我前面一篇文章Golang受欢迎的原因中已经提到,Golang是在语言层面(runtime)就支持了并发模型。那么作为编程人员,我们在实践Golang的并发编程时,又有什么需要注意的点呢?下面我会跟大家详细的介绍一些在实际生产编程中很容易踩坑的知识点。
CSP在介绍Golang的并发实践前,有必要先介绍简单介绍一下CSP理论。CSP,全称是Communicating sequential processes,翻译为通信顺序进程,又翻译为交换消息的顺序程序,用来描述并发性系统的交互模式。CSP有以下三个特点:
1.每个程序是为了顺序执行而创建的
2.数据通过管道来通信,而不是通过共享内存
3.通过增加相同的程序来扩容
Golang的并发模型基于CSP理论,Golang并发的口号是:不用通过共享内存来通信,而是通过通信来共享内存。
Golang并发模式Golang用来支持并发的元素集:
goroutines
channels
select
sync package
其中goroutines,channels和select 对应于实现CSP理论,即通过通信来共享内存。这几乎能解决Golang并发的90%问题,另外的10%场景需要通过同步原语来解决,即sync包相关的结构。
看图识channel如上图所示,我们从一个简单的沙桶传递小游戏来认识Golang中的channel。其中蓝色的Gopher为发送方,紫色的Gopher为接受方,中间的灰色Gopher代表channel的缓冲区大小。
channel介绍 阻塞channel
不带buffer的channel阻塞情况:
unbuffered := make(chan int) a := <- unbuffered // 阻塞 unbuffered := make(chan int) // 1) 阻塞 a := <- unbuffered // 2) 阻塞 unbuffered <- 1 // 3) 同步 go func() { <-unbuffered }() unbuffered <- 1