Resumo dos cenários de uso de Contexto em golang

Quando a corrotina pai introduzida no go 1.7 deseja fechar a corrotina filha, é chamada a função de cancelamento do seu contexto, que enviará um sinal ao seu canal.

A função do Contexto pode ser refletida em dois aspectos: enviar sinais de terminação para métodos; passar alguns dados comuns para múltiplos métodos.

As quatro principais estruturas de Contexto, o uso de CancelContext, TimeoutContext, DeadLineContext e ValueContext

Quais são os cenários aplicáveis?

Por algum motivo (tempo limite ou saída forçada) queremos abortar a tarefa de cálculo desta goroutine, então podemos usar este Contexto

Componentes comuns de controle de simultaneidade: waitGroup, Context

Cenários de uso específicos:

1. Uso de Rpc, solicitação http. Agrupados em uma categoria estão os tempos limite usando withCancel. cancel() será chamado várias vezes e a chamada de cancelamento no pacote de contexto é idempotente. Você pode chamá-lo várias vezes com confiança. Controle paralelo assíncrono, se uma determinada chamada falhar, outras chamadas não serão afetadas

exemplo de código

package main

import (
    "context"
    "fmt"
    "math/rand"
    "net/http"
    "os"
    "time"
)

func main(){
//context控制并发  WithCancel  cancel()
    ctx,cancel := context.WithCancel(context.Background())
   go Worker(ctx,"01")
   go Worker(ctx,"02")
   go Worker(ctx,"03")
    time.Sleep(time.Second * 5)
    fmt.Println("stop all")
    cancel()
    time.Sleep(time.Second * 1)
}

func Worker(ctx context.Context,name string ) {
    for {
        select{
        case <- ctx.Done():
            fmt.Println(name," stop the goroutine!")
            return
        default:
            fmt.Println(name," ing")
            time.Sleep(time.Second *1)
        }
    }
}

//结果打印:
//01  ing
//02  ing
//02  ing
//03  ing
//01  ing
//01  ing
//02  ing
//03  ing
//02  ing
//01  ing
//03  ing
//01  ing
//02  ing
//03  ing
//stop all
//02  stop the goroutine!
//03  stop the goroutine!
//01  stop the goroutine!

context WithCancel cancela o controle e envia um sinal de cancelamento para garantir que todas as goroutines emanadas desta lógica sejam canceladas com sucesso.

2. As solicitações do servidor HTTP transferem dados WithValue entre si. WithContext é frequentemente usado em interceptadores.Após a verificação do cookie, as informações públicas são armazenadas na solicitação e a interface pode recuperá-las sozinha.

exemplo de código

// WithValue 使用
func main(){
    ContextWithValue()
}

func ContextWithValue() {
    rand.Seed(time.Now().Unix())
    ctx := context.WithValue(context.Background(), keyID, rand.Int())
    operation1(ctx)
}

func operation1(ctx context.Context) {
    fmt.Println("operation1 for id:", ctx.Value(keyID), " completed")
    operation2(ctx)
}

func operation2(ctx context.Context) {
    fmt.Println("operation2 for id:", ctx.Value(keyID), " completed")
}

3. Solicitação de tempo limite. rpc chama http e chama WithTimeout WithDeadLine (operações demoradas, como arquivo io ou rede io, podem verificar se o tempo restante é suficiente para decidir se deve prosseguir para a próxima etapa)

Os parâmetros de tempo passados ​​em WithDeadLine e withTimeout são diferentes, mas o resto é o mesmo.

Exemplo de código WithTimeout

import (
    "context"
    "fmt"
    "math/rand"
    "net/http"
    "os"
    "time"
)


// WithTimeout
func main(){
// 创建一个空ctx
    ctx := context.Background()
    // 设置超时时间
    cxt, _ := context.WithTimeout(ctx, 1*time.Millisecond)

    start := time.Now()
    // 创建一个请求 访问谷歌
    req, _ := http.NewRequest(http.MethodGet, "http://baidu.com", nil)
    // 将带有取消方法的ctx和请求关联
    req = req.WithContext(cxt)

    client := &http.Client{}
    res, err := client.Do(req)
    if err!=nil{
        fmt.Println("Request failed:", err ," time ",time.Now().Sub(start))

        return
    }
    fmt.Println("Response received, status code:", res.StatusCode)
}
WithTimeout代码示例
func main(){
    ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second * 4))
    defer cancel()
    copyFileWithDeadline(ctx)
    time.Sleep(time.Second * 5)
}

func copyFileWithDeadline(ctx context.Context)  {
    deadline, ok := ctx.Deadline()
    if ok == false {
        return
    }
    // deadline.Sub(time.Now()) 截止时间与当前时间的差值
    isEnough := deadline.Sub(time.Now()) > time.Second * 5
    if isEnough {
        fmt.Println("copy file")
    } else {
        fmt.Println("isEnough is false return")
        return
    }
}

Exemplo de código de simultaneidade controlada por contexto. Observe que a ordem de execução das corrotinas é aleatória. Mas waitgroup é um controle de simultaneidade que pode garantir a execução sequencial.

package main

import (
    "context"
    "fmt"
    "math/rand"
    "net/http"
    "os"
    "time"
)

func main(){
//context控制并发  WithCancel  cancel()
    ctx,cancel := context.WithCancel(context.Background())
   go Worker(ctx,"01")
   go Worker(ctx,"02")
   go Worker(ctx,"03")
    time.Sleep(time.Second * 5)
    fmt.Println("stop all")
    cancel()
    time.Sleep(time.Second * 1)
}

func Worker(ctx context.Context,name string ) {
    for {
        select{
        case <- ctx.Done():
            fmt.Println(name," stop the goroutine!")
            return
        default:
            fmt.Println(name," ing")
            time.Sleep(time.Second *1)
        }
    }
}

//结果打印:
//01  ing
//02  ing
//02  ing
//03  ing
//01  ing
//01  ing
//02  ing
//03  ing
//02  ing
//01  ing
//03  ing
//01  ing
//02  ing
//03  ing
//stop all
//02  stop the goroutine!
//03  stop the goroutine!
//01  stop the goroutine!

func main(){
// waitgroup来控制并发
    wg := sync.WaitGroup{}
    wg.Add(2)
    go func(){
        fmt.Println("1 job")
        wg.Done()
    }()
    go func(){
        fmt.Println(" 2 job")
        wg.Done()
    }()
    wg.Wait()
    fmt.Println(" end")
}

Resumo final:

1. Transferência de valor. --A transferência de valor é apenas uma função auxiliar de contexto, comumente usada: cookies, interceptadores ou informações de log, depuração de registros de informações

2. Controle de tempo limite - tempo limite de configuração http, chamada rpc, - operações demoradas, como arquivo io ou rede io, podem verificar se o tempo restante é suficiente e decidir se devem prosseguir para a próxima etapa.

3. Controle de cancelamento - envie um sinal de cancelamento para garantir que todas as goroutines provenientes de sua própria lógica sejam canceladas com sucesso

Acho que você gosta

Origin blog.csdn.net/xia_2017/article/details/128821215
Recomendado
Clasificación