• golang context


    ex1

    package main
    
    import (	
    	"fmt"
    )
    
    // 最佳context 实践
    //  Context 目标是实现各个goroutine能及时终止退出。
    
    
    func main() {
    	// Basic ipfsnode setup	
    	a := 10
    	fmt.Println("hhha")
    	fmt.Println(a)	
    }
    

    ex2

    package 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终止时间线, 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{}
    }
    */
    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终止时间线, 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{}
    }
    */
    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, cancel := context.WithDeadline(context.Background(), 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)
    		}
    	}
    }
    
  • 相关阅读:
    Atitit 编程语言编程方法的进化演进 sp  COP ,AOP ,SOP
    Atitit 2016年attilax事业成就表
    Atitit 知识管理的重要方法 数据来源,聚合,分类,备份,发布 搜索
    Atitit webservice发现机制 WS-Discovery标准的规范attilax总结
    Atitit 多元化战略 适合我们发展 的核心业务attilax总结
    Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结
    Atitit. 提升存储过程与编程语言的可读性解决方案v3 qc25.docx
    Atitit zxing二维码qr码识别解析
    Atitit Data Matrix dm码的原理与特点
    Atitit 常用二维码对比(QR、PDF417、DM、汉信码 Aztec code maxicode
  • 原文地址:https://www.cnblogs.com/freebird92/p/10518400.html
Copyright © 2020-2023  润新知