背景知识
在传统的并发模型中,基于内存分享,各线程通信,需要通过共享变量以及锁的同步机制。并且共享变量很麻烦,要保证:
- 内存可见性,保证其他线程可以看到修改后的值
- 原子性
Go语言的并发编程
Go语言里有同步的包,类似于Java concurrent包,能够提供锁的功能,但是不是太推荐。Go语言里提倡基于消息传递的并发模型,不共享变量,因此就不涉及锁的问题。
虽然说Go语言里的Goroutine不是真正意义上的协程,但是有时我们就称呼它为“协程”。
- 一个go关键词就可以起一个新的Go协程(注意:跟底层协程不是完全相等的)
func say(s string)
{
for i:=0;i<5;i++
{
time.Sleep(1 * time.second)
fmt.Println(s)
}
}
func main()
{
go say("world")
say("hello")
}
- 不同Goroutine之间用信道chan来通信,不使用共享变量。用make(chan关键字,数据类型)创建信道。
注意:
- 只有发送者才能关闭信道,而接受者不能。向一个已经关闭的信道发送数据会引发程序恐慌。
- 信道与文件不同,通常情况下无需关闭它们。
- select语句使一个Go程可以等待多个通信操作。select会阻塞到某个分支可以继续为止,这时就会执行该分支。当多个分支都准备好时会随机选择一个执行。