作者回复: context就是用于管理相关任务的上下文,包含了共享值的传递,超时,取消通知 type Context interface { Deadline() (deadline time.Time, ok bool) Done() <-chan struct{} Err() error Value(key interface{}) interface{} } Deadline会返回一个超时时间,Goroutine获得了超时时间后,例如可以对某些io操作设定超时时间。 Done方法返回一个信道(channel),当Context被撤销或过期时,该信道是关闭的,即它是一个表示Context是否已关闭的信号。 当Done信道关闭后,Err方法表明Context被撤的原因。 Value可以让Goroutine共享一些数据,当然获得数据是协程安全的。但使用这些数据的时候要注意同步,比如返回了一个map,而这个map的读写则要加
作者回复: 这个cancel就是由相关的context生成的。参考下面的实例代码: package cancel_with_ctx import ( "fmt" "testing" ) func WithContext(ctx int) (Cancel func()) { return func() { fmt.Println("The value of ctx is ", ctx) } } func TestWithContext(t *testing.T) { cancel := WithContext(10) cancel() //output: The value of ctx is 10 }
作者回复: 推荐你一个,简单的 https://github.com/easierway/service_decorators/blob/master/README.md
作者回复: 你的“fmt.Println(" ctx4 canceled")” 位置不对 package hh import ( "context" "fmt" "testing" "time" ) func isCancel(ctx context.Context) bool { select { case <-ctx.Done(): return true default: return false } } func TestContextCancelling(t *testing.T) { ctx := context.Background() // ctx2 是子context ,cancel 是取消函数 ctx2, cancel := context.WithCancel(ctx) for i := 0; i < 5; i++ { go func(i int, ctx3 context.Context) { for { if isCancel(ctx3) { break } time.Sleep(time.Millisecond * 10) } fmt.Println(i, "canceled") }(i, ctx2) // 传递子context } // 然后再通过子context创建孙context ctx4, _ := context.WithCancel(ctx2) go func(ctx4 context.Context) { fmt.Println("ctx4 started") for { if isCancel(ctx4) { break } //time.Sleep(time.Millisecond * 10) } fmt.Println(" ctx4 canceled") }(ctx4) cancel() time.Sleep(time.Second * 10) }