英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论