File tree Expand file tree Collapse file tree 3 files changed +154
-0
lines changed
Expand file tree Collapse file tree 3 files changed +154
-0
lines changed Original file line number Diff line number Diff line change 1+ package main
2+
3+ import (
4+ "context"
5+ "fmt"
6+ "time"
7+ )
8+
9+ // 直接使用parent cancelCtx
10+ func f1 (ctx context.Context ) {
11+ go func () {
12+ select {
13+ case <- ctx .Done ():
14+ fmt .Println ("goroutine created by f1 exit" )
15+ }
16+ }()
17+ }
18+
19+ // 基于parent cancelCtx创建新的cancelCtx
20+ func f2 (ctx context.Context ) {
21+ ctx1 , _ := context .WithCancel (ctx )
22+ go func () {
23+ select {
24+ case <- ctx1 .Done ():
25+ fmt .Println ("goroutine created by f2 exit" )
26+ }
27+ }()
28+ }
29+
30+ // 使用基于parent cancelCtx创建的valueCtx
31+ func f3 (ctx context.Context ) {
32+ ctx1 := context .WithValue (ctx , "key3" , "value3" )
33+ go func () {
34+ select {
35+ case <- ctx1 .Done ():
36+ fmt .Println ("goroutine created by f3 exit" )
37+ }
38+ }()
39+ }
40+
41+ // 基于parent cancelCtx创建的valueCtx之上创建cancelCtx
42+ func f4 (ctx context.Context ) {
43+ ctx1 := context .WithValue (ctx , "key4" , "value4" )
44+ ctx2 , _ := context .WithCancel (ctx1 )
45+ go func () {
46+ select {
47+ case <- ctx2 .Done ():
48+ fmt .Println ("goroutine created by f4 exit" )
49+ }
50+ }()
51+ }
52+
53+ func main () {
54+ valueCtx := context .WithValue (context .Background (), "key0" , "value0" )
55+ cancelCtx , cf := context .WithCancel (valueCtx )
56+ f1 (cancelCtx )
57+ f2 (cancelCtx )
58+ f3 (cancelCtx )
59+ f4 (cancelCtx )
60+
61+ time .Sleep (3 * time .Second )
62+ fmt .Println ("cancel all by main" )
63+ cf ()
64+ time .Sleep (10 * time .Second ) // wait for log output
65+ }
Original file line number Diff line number Diff line change 1+ package main
2+
3+ import (
4+ "context"
5+ "fmt"
6+ "runtime"
7+ "time"
8+ )
9+
10+ func f1 (ctx context.Context ) {
11+ ctx1 , _ := context .WithCancel (ctx )
12+ go func () {
13+ select {
14+ case <- ctx1 .Done ():
15+ fmt .Println ("goroutine created by f1 exit" )
16+ }
17+ }()
18+ }
19+
20+ type myCancelCtx struct {
21+ context.Context
22+ done chan struct {}
23+ err error
24+ }
25+
26+ func (ctx * myCancelCtx ) Done () <- chan struct {} {
27+ return ctx .done
28+ }
29+
30+ func (ctx * myCancelCtx ) Err () error {
31+ return ctx .err
32+ }
33+
34+ func WithMyCancelCtx (parent context.Context ) (context.Context , context.CancelFunc ) {
35+ var myCtx = & myCancelCtx {
36+ Context : parent ,
37+ done : make (chan struct {}),
38+ }
39+
40+ return myCtx , func () {
41+ myCtx .done <- struct {}{}
42+ myCtx .err = context .Canceled
43+ }
44+ }
45+
46+ func main () {
47+ valueCtx := context .WithValue (context .Background (), "key0" , "value0" )
48+ fmt .Println ("before f1:" , runtime .NumGoroutine ())
49+
50+ myCtx , mycf := WithMyCancelCtx (valueCtx )
51+ f1 (myCtx )
52+ fmt .Println ("after f1:" , runtime .NumGoroutine ())
53+
54+ time .Sleep (3 * time .Second )
55+ mycf ()
56+ time .Sleep (10 * time .Second ) // wait for log output
57+ }
Original file line number Diff line number Diff line change 1+ package main
2+
3+ import (
4+ "context"
5+ "fmt"
6+ )
7+
8+ func f3 (ctx context.Context , req any ) {
9+ fmt .Println (ctx .Value ("key0" ))
10+ fmt .Println (ctx .Value ("key1" ))
11+ fmt .Println (ctx .Value ("key2" ))
12+ }
13+
14+ func f2 (ctx context.Context , req any ) {
15+ ctx2 := context .WithValue (ctx , "key2" , "value2" )
16+ f3 (ctx2 , req )
17+ }
18+
19+ func f1 (ctx context.Context , req any ) {
20+ ctx1 := context .WithValue (ctx , "key1" , "value1" )
21+ f2 (ctx1 , req )
22+ }
23+
24+ func handle (ctx context.Context , req any ) {
25+ ctx0 := context .WithValue (ctx , "key0" , "value0" )
26+ f1 (ctx0 , req )
27+ }
28+
29+ func main () {
30+ rootCtx := context .Background ()
31+ handle (rootCtx , "hello" )
32+ }
You can’t perform that action at this time.
0 commit comments