golang context包的使用
阿新 • • 發佈:2020-07-24
go Context
如何在一個goroutine中去通知其他的goroutine退出任務
package main import ( "context" "fmt" "time" ) func test1(ctx context.Context) { Block: for { select { case <-ctx.Done(): fmt.Println("test1 over") break Block default: time.Sleep(time.Second * 1) fmt.Println("test1......") } } } func test2(ctx context.Context) { Block: for { select { case <-ctx.Done(): fmt.Println("test2 over") break Block default: time.Sleep(time.Second * 1) fmt.Println("test2......") } } } func main() { ctx, cancel := context.WithCancel(context.Background()) go test1(ctx) go test2(ctx) time.Sleep(5 * time.Second) cancel() time.Sleep(5 * time.Second) }
WithCancel
:接受一個context引數,返回ctx和一個函式,當函式被呼叫,ctx的Done
方法將不再阻塞。
package main import ( "context" "fmt" "time" ) func test1(ctx context.Context) { Block: for { select { case <-ctx.Done(): fmt.Println("test1 over") break Block default: time.Sleep(time.Second * 1) fmt.Println("test1......") } } } func test2(ctx context.Context) { Block: for { select { case <-ctx.Done(): fmt.Println("test2 over") break Block default: time.Sleep(time.Second * 1) fmt.Println("test2......") } } } func main() { t := time.Now().Add(3 * time.Second) ctx, cancel := context.WithDeadline(context.Background(), t) go test1(ctx) go test2(ctx) time.Sleep(5 * time.Second) fmt.Println("main over") cancel() }
WithDeadline
:接受一個context引數和一個具體的過期時間點,返回一個context引數和一個函式,當函式主動呼叫時,ctx的Done
方法將不再阻塞,或者當本地時間大於等於過期的時間點時,ctx
的Done
方法也不再阻塞。
package main import ( "context" "fmt" "time" ) func test1(ctx context.Context) { Block: for { select { case <-ctx.Done(): fmt.Println("test1 over") break Block default: time.Sleep(time.Second * 1) fmt.Println("test1......") } } } func test2(ctx context.Context) { Block: for { select { case <-ctx.Done(): fmt.Println("test2 over") break Block default: time.Sleep(time.Second * 1) fmt.Println("test2......") } } } func main() { t := time.Duration(2) * time.Second ctx, cancel := context.WithTimeout(context.Background(), t) go test1(ctx) go test2(ctx) time.Sleep(5 * time.Second) fmt.Println("即將結束") cancel() fmt.Println("結束") }
WithTimeout
: 和WithDeadline
一樣,它接受的是一個相對時間,到達過期時間點後ctx的Done
不再阻塞, 也可以主動呼叫cancel
來提前結束
package main
import (
"context"
"fmt"
"time"
)
func test1(ctx context.Context) {
fmt.Println(ctx.Value("key"))
}
func main() {
ctx := context.WithValue(context.Background(), "key", "value")
go test1(ctx)
time.Sleep(1 * time.Second)
}
WithValue
: 可以在Context之間進行值得傳遞