golang的子协程内部阻塞处理时,怎么及时的判断超时,从而不导致 继续写入一个 应为超时而早已被关闭的channel引发的panic

@Ta 04-30 09:52发布,04-30 10:26修改 1396点击

代码如下

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"
回复列表(2|隐藏机器人聊天)
添加新回复
回复需要登录