golang context
发布时间:2020-12-16 09:29:37 所属栏目:大数据 来源:网络整理
导读:ex1 package mainimport ( "fmt")// 最佳context 实践// Context 目标是实现各个goroutine能及时终止退出。func main() { // Basic ipfsnode setup a := 10 fmt.Println("hhha") fmt.Println(a) } ex2 package mainimport "fmt"// 打印输出, 发送数据到通道
ex1package main import ( "fmt" ) // 最佳context 实践 // Context 目标是实现各个goroutine能及时终止退出。 func main() { // Basic ipfsnode setup a := 10 fmt.Println("hhha") fmt.Println(a) } ex2package main import "fmt" // 打印输出, 发送数据到通道 func printHello(ch chan int) { fmt.Println("Hello from printHello") // 发送一个数据到通道 ch <- 2 } func main() { /* 使用make函数,创建一个通道。 通道是可以带缓冲的, 如果你指定了长度。如ch := make(chan int,2) channel可分为三种类型: 只读channel:只能读channel里面数据,不可写入 只写channel:只能写数据,不可读 一般channel:可读可写 */ ch := make(chan int) //内联goroutine. 定义一个函数,直接go调用. //结束时,往通道发一个数据作为信号 go func(){ fmt.Println("Hello inline") //send a value on channel ch <- 1 }() //调用一个函数作为 goroutine go printHello(ch) fmt.Println("Hello from main") //首先从通道中取出一个数据, 并赋值给变量,并打印出来 i := <- ch fmt.Println("Recieved ",i) //从通道获取第二个数据 // 如果不需要它, 可以不赋值给变量 <- ch } ex3/* context(上下文): 可以理解为timeout(超时),deadline(终止时间线), 或者一个channel(通道)来指示goroutine停止工作并退出 比如,在系统中, 当调用其它网站的接口时,通常速度比较慢, 但是你又依赖它的及时返回, 所以并不打算把这个进行备份请求。 通常会设置一个超时。 */ /* 结构如下 // deadline终止时间线,cancelation 取消信号,and request-scoped 请求范围值 // 多个goroutines同时使用,是安全的 type Context interface { // Done 方法在Context被取消或超时时返回一个close的channel,close的channel可以作为广播通知,告诉给context相关的函数要停止当前工作然后返回。 // 当一个父operation启动一个goroutine用于子operation,这些子operation不能够取消父operation。下面描述的WithCancel函数提供一种方式可以取消新创建的Context. // Context可以安全的被多个goroutine使用。开发者可以把一个Context传递给任意多个goroutine然后cancel这个context的时候就能够通知到所有的goroutine。 Done() <-chan struct{} // Err方法返回context为什么被取消。 Err() error // Deadline返回context何时会超时。 Deadline() (deadline time.Time,ok bool) // Value返回context相关的数据。 Value(key interface{}) interface{} } */ // 创建context上下文 // 1. context.Backgrond() ctx Context // BackGound是所有Context的root,不能够被cancel。 // 这个函数返回一个空的上下文, 这个仅在高层使用(如在main 或者 顶级请求) /* 2. WithCancel返回一个继承的Context,这个Context在父Context的Done被关闭时关闭自己的Done通道,或者在自己被Cancel的时候关闭自己的Done。 WithCancel同时还返回一个取消函数cancel,这个cancel用于取消当前的Context。 */ package main import ( "context" "log" "os" "time" ) var logg *log.Logger func someHandler() { ctx,cancel := context.WithCancel(context.Background()) go doStuff(ctx) //10秒后取消doStuff time.Sleep(10 * 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() { logg = log.New(os.Stdout,"",log.Ltime) someHandler() logg.Printf("down") } ex4/* context(上下文): withDeadline withTimeout */ /* 结构如下 // deadline终止时间线,ok bool) // Value返回context相关的数据。 Value(key interface{}) interface{} } */ package main import ( "context" "log" "os" "time" ) var logg *log.Logger //每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 timeoutHandler() { // 这里在上下文中加入了超时限制, 超时和取消,取其短。 ctx,cancel := context.WithDeadline(context.Background(),time.Now().Add(2 * time.Second)) go doStuff(ctx) time.Sleep(10 * time.Second) cancel() } func main() { logg = log.New(os.Stdout,log.Ltime) timeoutHandler() logg.Printf("end") } ex5/* context(上下文): withDeadline withTimeout */ /* 结构如下 // deadline终止时间线,ok bool) // Value返回context相关的数据。 Value(key interface{}) interface{} } */ package main import ( "context" "log" "os" "time" ) var logg *log.Logger //每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 doTimeOutStuff(ctx context.Context) { for { time.Sleep(1 * time.Second) if deadline,ok := ctx.Deadline(); ok { //设置了deadl logg.Printf("deadline set") if time.Now().After(deadline) { logg.Printf(ctx.Err().Error()) return } } select { case <-ctx.Done(): logg.Printf("done") return default: logg.Printf("work") } } } func timeoutHandler() { ctx,cancel := context.WithTimeout(context.Background(),5*time.Second) // ctx,time.Now().Add(5*time.Second)) go doTimeOutStuff(ctx) // go doStuff(ctx) time.Sleep(10 * time.Second) cancel() } func main() { logg = log.New(os.Stdout,log.Ltime) timeoutHandler() logg.Printf("end") } ex6/* context(上下文): withValue 附加一些(不可变)数据, 供派生goroutine查询用 */ package main import ( "context" "log" "os" "time" ) const ( GOLABLE_KEY = "test123" ) func main() { //父context控制子context controlAllConrrent() } func controlAllConrrent() { logg := log.New(os.Stdout,log.Ltime) handleSome() logg.Println("over ") } //父协程 func handleSome() { //ctx,cancelFunc := context.WithCancel(context.Background()) //ctx,cancelFunc := context.WithTimeout(context.Background(),time.Second*2) ctx,cancelFunc := context.WithDeadline(context.Background(),time.Now().Add(time.Second*2)) ctx = context.WithValue(ctx,GOLABLE_KEY,"1234") go workerFunc(ctx,"str1") go workerFunc(ctx,"str2") time.Sleep(time.Second * 3) cancelFunc() } //子协程 func workerFunc(ctx context.Context,showStr string) { for { time.Sleep(time.Second * 1) select { case <-ctx.Done(): log.Println("done") return default: val123 := ctx.Value(GOLABLE_KEY).(string) log.Println(val123,showStr) } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |