Go语言的并发
原子操作
可以利用sync包中的Mutex对于资源进行加锁,从而保证资源的原子性。但其实Go官方并不推荐这种方法,更提倡用通信的方法来进行内存的共享。
不要以共享内存的方式来通信,作为替代,我们应该以通信的手段来共享内存
基于信道的通信
channel是在Goroutine之间进行同步的主要方法,读写通过“->”完成
通过make函数进行声明
可能出现错误的操作
-
关闭一个未初始化(nil) 的 channel 会产生 panic
-
重复关闭同一个 channel 会产生 panic
-
向一个已关闭的 channel 中发送消息会产生 panic
-
从已关闭的 channel 读取消息不会产生 panic,且能读出 channel 中还未被读取的消息,若消息均已读出,则会读到类型的零值。从一个已关闭的 channel 中读取消息永远不会阻塞,并且会返回一个为 false 的 ok-idiom,可以用它来判断 channel 是否关闭
-
关闭 channel 会产生一个广播机制,所有向 channel 读取消息的 goroutine 都会收到消息
无缓存
无论是写入还是读取channel都会阻塞,直到另外一个goroutine读取或写入这个channel
带缓存
当缓存满时,写入channel会阻塞,直到另外一个goroutine取走一个数据。
当缓存为空时,读取channel会阻塞,直到另外一个goroutine写入一个数据。
使用select同时监听多个channel
select {
case <- ch1:
...
case <- ch2:
...
case ch3 <- 10;
...
default:
...
}
如果没有定义default操作,那么当所有的channel都阻塞的时候,select也会阻塞。
这个只能监听一次消息,如果想要一直监听的话。
msgCh := make(chan