Golang Context案例

Golang Context案例

Golang 中的 Context 使用包括 WithCancel、WithDeadline、WithTimeout 和 WithValue。

WithCancel案例

语法

// WithCancel returns a copy of parent whose Done channel is closed as soon as // parent.Done is closed or cancel is called. func WithCancel(parent Context) (ctx Context, cancel CancelFunc)

案例

package main import ( "context" "fmt" "log" "os" "time" ) var logg *log.Logger func someHandler() { ctx, cancel := context.WithCancel(context.Background()) go doStuff(ctx) //5秒后取消doStuff time.Sleep(5 * time.Second) cancel() } //每1秒work一下,同时会判断ctx是否被取消了,如果是就退出 func doStuff(ctx context.Context) { for { time.Sleep(1 * time.Second) select { case <-ctx.Done(): logg.Printf("done") return default: logg.Printf("work") } } } func main() { fmt.Println("嗨客网(www.haicoder.net)") logg = log.New(os.Stdout, "", log.Ltime) someHandler() logg.Printf("down") }

运行后,如下图所示:

51_Go语言Context案例.png

WithCancel 返回一个继承的 Context,这个 Context 在父 Context 的 Done 被关闭时关闭自己的 Done 通道,或者在自己被 Cancel 的时候关闭自己的 Done。
WithCancel 同时还返回一个取消函数 cancel,这个 cancel 用于取消当前的 Context。

WithDeadline案例

语法

func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)

案例

package main import ( "context" "fmt" "log" "os" "time" ) var logg *log.Logger func timeoutHandler() { ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second)) go doStuff(ctx) time.Sleep(100 * time.Second) logg.Printf("Send Cancel") cancel() } //每1秒work一下,同时会判断ctx是否被取消了,如果是就退出 func doStuff(ctx context.Context) { for { time.Sleep(1 * time.Second) select { case <-ctx.Done(): logg.Printf("done") return default: logg.Printf("work") } } } func main() { fmt.Println("嗨客网(www.haicoder.net)") logg = log.New(os.Stdout, "", log.Ltime) timeoutHandler() logg.Printf("down") }

运行后,如下图所示:

52_Go语言Context案例.png

可以看到 doStuff 在 context 超时的时候被取消了,ctx.Done() 被关闭。

WithTimeout案例

语法

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

案例

package main import ( "context" "fmt" "log" "os" "time" ) var logg *log.Logger func timeoutHandler() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) go doStuff(ctx) time.Sleep(100 * time.Second) logg.Printf("Send Cancel") cancel() } //每1秒work一下,同时会判断ctx是否被取消了,如果是就退出 func doStuff(ctx context.Context) { for { time.Sleep(1 * time.Second) select { case <-ctx.Done(): logg.Printf("done") return default: logg.Printf("work") } } } func main() { fmt.Println("嗨客网(www.haicoder.net)") logg = log.New(os.Stdout, "", log.Ltime) timeoutHandler() logg.Printf("down") }

运行后,如下图所示:

53_Go语言Context案例.png

WithTimeout 等价于 WithDeadline(parent, time.Now().Add(timeout)).

Golang Context案例总结

Golang 中的 Context 使用包括 WithCancel、WithDeadline、WithTimeout 和 WithValue。