go通过channel进行goroutine之间的通信
在go语言中,两个协程之间进行通信,使用的是一种消息队列的形式。消息的生产者将消息放入消息队列,然后消费者从消息队列中获取消息。
go提供了一个数据类型和语法糖来完成这种操作 channel
、 <-
例如:
func main() {
var msg chan string
msg = make(chan string, 1)
msg <- "哈喽,哈喽!"
data := <- msg
fmt.Println(data)
}
channel的使用需要初始化,并且需要显性的指明缓冲区大小
chan 后面跟着的是channel中放的数据类型,这个同样需要显性的指明
运行结果应该是:
哈喽,哈喽!
当缓冲区大小为0时,不能直接的在一个协程中写入和读取
例如:
func main() {
var msg chan string
msg = make(chan string, 0) // 缓冲区大小设为0
msg <- "哈喽,哈喽!"
data := <- msg
fmt.Println(data)
}
运行之后会报死锁:
fatal error: all goroutines are asleep - deadlock!
此时,由于go语言有一种happen-before的机制,让我们可以使用一个另外的goroutine来读取,例如:
func main() {
var msg chan string
var wg sync.WaitGroup
wg.Add(1)
msg = make(chan string, 0) // 缓冲区大小设为0
go func(msg chan string) {
defer wg.Done()
data := <- msg
fmt.Println(data)
}(msg)
msg <- "哈喽,哈喽!"
wg.Wait()
}
运行结果为:
哈喽,哈喽!