代码如下
package main
import (
"context"
"os"
"time"
)
func main() {
g()
//模拟全局线程继续运行
time.Sleep(time.Second * 5)
}
func g() {
// 创建一个子节点的context,3秒后自动超时
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer func() {
cancel()
println("g()函数已完结")
}()
channel := make(chan string)
defer close(channel)
// 创建一个子协程 用于某些阻塞的操作
go func() {
defer println("(block)子携程退出", os.Getppid())
select {
case <-ctx.Done():
return
default:
time.Sleep(time.Millisecond * 100)
//1获取到一些数据后,结果发送到channel
channel <- "hello"
time.Sleep(time.Second * 4)
//2获取到一些数据后,结果发送到channel
channel <- "hello"
}
}()
select {
case <-ctx.Done():
return
case h := <-channel:
println("收到消息", h)
}
}
错误:
收到消息 hello
g()函数已完结
(block)子携程退出 1616
panic: send on closed channel
goroutine 6 [running]:
main.g.func2()
C:/Users/admin/IdeaProjects/testg/main.go:39 +0xa5
created by main.g in goroutine 1
C:/Users/admin/IdeaProjects/testg/main.go:27 +0x125
每次 channel <- "hello"
的时候用,但是有临界问题,如果刚判断完毕channel可用(临界值),然后就被close(channel)
,还是会出现panic: send on closed channel,难道需要还要额外加入一个写锁判断吗
_,ok:=<-channel;
ok && channel <- "hello"
https://go101.org/article/channel-closing.html