O principal objetivo do contexto do golang é transferir dados entre várias goroutines e gerenciar o ciclo de vida de várias goroutines. Os cenários reais do aplicativo estão, por exemplo, no serviço http, cada solicitação corresponde a uma goroutine e outras APIs podem ser chamadas na solicitação para gerar mais goroutines.É mais conveniente usar o contexto para gerenciar essas goroutines. Transfira dados e gerenciamento nessas goroutines.
Método principal
func Background() Context
Background () retorna um contexto vazio, que é um nó raiz.
func TODO() Context
TODO () retorna um contexto vazio. A diferença entre ele e o plano de fundo é o objetivo.Quando você usa um contexto de tarefas, o mantenedor do código sabe que a intenção do design naquele momento está pendente.
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
WithCancel () deriva um contexto filho com um método cancel, que é muito útil ao manipular recursivamente o contexto.
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
WithDeadline () e WithTimeout () não são os mesmos, exceto que os parâmetros passados pelos dois são diferentes, um é o tempo limite e o outro é o intervalo de tempo.
func WithValue(parent Context, key interface{}, val interface{}) Context
WithValue () pode levar alguns parâmetros no contexto.
Princípios de gerenciamento de goroutine
Após uma breve compreensão do método de contexto, vamos explorar por que o contexto pode gerenciar a goroutina. Primeiro, veja um pequeno exemplo:
func doSomething(ch chan int, id int) {
fmt.Println(id)
t := rand.Intn(10)
time.Sleep(time.Duration(t) * time.Second)
fmt.Printf("I had slept %d seconds.\n", t)
ch <- 1
}
func SomeGoRoutine() {
ch := make(chan int)
for i := 0; i < 3; i++ {
go doSomething(ch, i)
}
<-ch
fmt.Println("done")
}
/** output:
2
0
1
I had slept 1 seconds.
done
*/
Nesse cenário, meu serviço http fornece uma API e n goroutines são geradas nessa API. Quando ocorrer um erro em uma das goroutines, desejo encerrar a solicitação inteira e retornar algumas mensagens de erro ao chamador. Se você não usa o contexto, podemos facilmente pensar em usar o canal para obter essa função, bloquear a função principal, passar dados para o canal na goroutine e encerrar a solicitação quando o canal receber os dados. O contexto também é um princípio semelhante, o gerenciamento de goroutine é alcançado através da transferência de canais entre goroutine. O mais interessante é o método WithCancel, que é diferente do uso simples de canais para transmitir dados.O WithCancel deriva um contexto filho, quando o contexto filho está prestes a terminar, chama o método cancel recursivamente e seu filho também chama o método cancel . Exemplos são os seguintes:
func ContextCancel() {
ctx := context.Background()
go func(ctx context.Context) {
ctx1, cancel := context.WithCancel(ctx)
go func(ctx1 context.Context) {
ctx2, _ := context.WithCancel(ctx1)
select {
case <-ctx2.Done():
fmt.Println("ctx2")
}
}(ctx1)
cancel()
}(ctx)
time.Sleep(10 * time.Second)
}
/** ouput:
ctx2
*/
Bem-vindo a prestar atenção ao meu número público: onepunchgo, deixe-me uma mensagem.