Golang 中的 Context 使用包括 WithCancel、WithDeadline、WithTimeout 和 WithValue。
// 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")
}
运行后,如下图所示:
WithCancel 返回一个继承的 Context,这个 Context 在父 Context 的 Done 被关闭时关闭自己的 Done 通道,或者在自己被 Cancel 的时候关闭自己的 Done。
WithCancel 同时还返回一个取消函数 cancel,这个 cancel 用于取消当前的 Context。
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")
}
运行后,如下图所示:
可以看到 doStuff 在 context 超时的时候被取消了,ctx.Done() 被关闭。
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")
}
运行后,如下图所示:
WithTimeout 等价于 WithDeadline(parent, time.Now().Add(timeout)).
Golang 中的 Context 使用包括 WithCancel、WithDeadline、WithTimeout 和 WithValue。