Fale sobre o contexto de golang

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.

imagem

Publicado 20 artigos originais · elogiado 0 · visitas 761

Acho que você gosta

Origin blog.csdn.net/qq_31362439/article/details/105006977
Recomendado
Clasificación