😎
Go言語context.WithCancelはどうやって動いています?
コード1
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
go process(ctx)
cancel()
time.Sleep(time.Hour)
}
func process(ctx context.Context) {
time.Sleep(time.Second)
<-ctx.Done()
fmt.Println("closed")
}
コードの動き
メイン関数のキャンセルにより、process関数の<-ctx.Done()が解除されます。
内部動き
- main関数にあるcancel()は先に実行されます。
- process関数にある<-ctx.Done()はあとで実行されます。
1が実行されるところはここです。
クローズされるチャンネルはパッケージがローディング時に実行されます。
2が実行されるところはここです。
コード2
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
go process(ctx)
time.Sleep(time.Second) // <- 追加した分
cancel()
time.Sleep(time.Hour)
}
func process(ctx context.Context) {
time.Sleep(time.Second)
<-ctx.Done()
fmt.Println("closed")
}
コードの動き
メイン関数のキャンセルにより、process関数の<-ctx.Done()が解除されます。
内部動き
追加した分により、processにあるctx.Doneは先に実行されます。そして、main関数にあるcancelが実行されます
1が実行されるところはここです。
2が実行されるところはここです。
Discussion