• golang context包的使用


    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方法将不再阻塞,或者当本地时间大于等于过期的时间点时,ctxDone方法也不再阻塞。

    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之间进行值得传递

  • 相关阅读:
    Bellman-Ford算法
    POJ 1990 MooFest
    POJ3067:Japan(树状数组求逆序对)
    树状数组求逆序对
    树状数组
    Is It A Tree?(hdu1325)
    强连通图 Tarjan算法
    UVALive
    UVALive
    Problem Statement
  • 原文地址:https://www.cnblogs.com/ivy-blogs/p/13370810.html
Copyright © 2020-2023  润新知