概述
golang channel 是我们常用的一个用于处理协程通信的最重要的工具, 在一些边界情况下的表现,差异化很大。
本文就golang在channel正常状态、关闭状态、nil 状态下的发送接收以及关闭的表现做一个简单的测试说明, 有任何疑问欢迎交流探讨。
channel在各种状态下的操作表现结论
通道操作 | 正常状态 | 关闭状态 | nil |
---|---|---|---|
发送 | √ | X (panic: send on closed channel) | X |
接收 | √ | √ (接收到的为初始值) | X |
关闭 | √ | X (panic: close of closed channel) | X |
正常发送和接收
示例代码
package main
import (
"fmt"
)
func main() {
ch := make(chan string)
go send(ch)
recv(ch)
close(ch) // 关闭
}
// 接收
func recv(ch <-chan string) {
x := <-ch
fmt.Println("result:", x)
}
// 发送
func send(ch chan<- string) {
ch <- "send_val"
}
复制代码
运行结果: (一切表现正常)
result: send_val
复制代码
关闭状态的channel进行操作
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string)
close(ch) // ok
close(ch) // panic: close of closed channel
go send(ch) // panic: send on closed channel
recv(ch) // result:
time.Sleep(time.Second)
}
func send(ch chan<- string) {
ch <- "send_val"
}
func recv(ch <-chan string) {
x := <-ch
fmt.Println("result:", x)
}
复制代码
nil
fatal error: all goroutines are asleep - deadlock!panic: close of nil channelfatal error: all goroutines are asleep - deadlock!
nilgoroutine 1 [chan receive (nil chan)]:
package main
import (
"fmt"
"time"
)
func main() {
var ch chan string
close(ch) // panic: close of nil channel
go recv(ch) // goroutine 1 [chan receive (nil chan)]:
send(ch) // fatal error: all goroutines are asleep - deadlock!
time.Sleep(time.Second)
}
func send(ch chan<- string) {
ch <- "send_val"
}
func recv(ch <-chan string) {
x := <-ch
fmt.Println("result:", x)
}
复制代码