英文:
about the key ”defer”and “select” in Go
问题
func TestContext(t *testing.T) {
message := make(chan int, 10)
//producer
for i := 0; i < 10; i++ {
message <- i
}
//consumer
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
go func(ctx context.Context) {
ticker := time.NewTicker(1 * time.Second)
for _ = range ticker.C {
select {
case <-ctx.Done():
fmt.Println("子进程中断...")
return
default:
fmt.Printf("发送消息:%d\n", <-message)
}
}
}(ctx)
defer close(message)
defer cancel()
select {
case <-ctx.Done():
//time.Sleep(1*time.Second)
fmt.Println("主进程退出!")
}
}
Q1: "defer cancel" 什么时候执行?在 select 之后吗?
Q2: 在 Q1 中,如果 "defer cancel" 在 select 之后执行,ctx.Done() 会返回 nil 吗?select 会被阻塞吗?
英文:
func TestContext(t *testing.T){
message:=make(chan int,10)
//producer
for i:=0;i<10;i++{
message<-i
}
//consumer
ctx,cancel:=context.WithTimeout(context.Background(),time.Second*5)
go func(ctx context.Context) {
ticker := time.NewTicker(1 * time.Second)
for _ = range ticker.C {
select {
case <-ctx.Done():
fmt.Println("child process interrupt...")
return
default:
fmt.Printf("send message: %d\n", <-message)
}
}
}(ctx)
defer close(message)
defer cancel()
select{
case <-ctx.Done():
//time.Sleep(1*time.Second)
fmt.Println("main process exit!")
}
}
Q1: when is the “defer cancel” executed? after select ?
Q2: In Q1,if "defer cancel" is executed after select , will the ctx.Done() return nil? and will the select be blocked?
答案1
得分: 3
所有延迟的函数调用将在函数体运行之后但在函数返回之前执行,所以是的,defer cancel
会在select
之后执行。
select
会阻塞直到上下文超时。当上下文超时时,<-ctx.Done()
的情况将被启用,所以select
可以在上下文超时后继续执行。
英文:
All deferred function calls will run after the function body runs, but before the function returns, so yes, defer cancel will execute after select
.
Select will block until the context times out. When the context times out, the <-ctx.Done()
case will be enabled, so select can continue after the context timeout.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论