Maison >développement back-end >Golang >Comment puis-je annuler gracieusement les Goroutines après un délai spécifié dans Go ?

Comment puis-je annuler gracieusement les Goroutines après un délai spécifié dans Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-19 19:25:03850parcourir

How Can I Gracefully Cancel Goroutines After a Specified Time Limit in Go?

Annulation des Goroutines après une limite de temps

Dans les scénarios de tests de charge, contrôler la durée d'exécution des Goroutines est crucial. Voici une approche efficace pour y parvenir.

Considérez l'extrait de code suivant qui gère les requêtes HTTP dans les Goroutines :

func attack(cfg AttackConfig) {
    // some code ...

    var ar attackResponse
    ch := make(chan uint8, 8)

    go func() {
        time.Sleep(cfg.Duration * time.Second)
        ch <- CALL_TIME_RAN_OUT
    }()

    for {
        if atomic.LoadInt32(&currConnections) < atomic.LoadInt32(&maxConnections) - 1 {
            go httpPost(cfg, &ar, ch)
        }

        switch <-ch {
        // some other cases ...
        case CALL_TIME_RAN_OUT:
            fmt.Printf("%d seconds have elapsed. Shutting down!", cfg.Duration)
            return
        }
    }
}

Cependant, les Goroutines de httpPost() continuent de s'exécuter après la cfg.Duration spécifiée. s'est écoulé.

Pour résoudre ce problème, vous pouvez tirer parti du package contextuel de Go. En passant un objet context.Context à vos Goroutines, vous pouvez annuler ces Goroutines lorsque le délai d'attente spécifié est atteint.

Voici une version révisée de votre code utilisant le package de contexte :

import (
    "context"
    "fmt"
    "golang.org/x/net/context"
    "time"
)

func attack(cfg AttackConfig) {
    // some code ...

    var ar attackResponse

    // Define a timeout context
    ctx, cancel := context.WithTimeout(context.Background(), cfg.Duration*time.Second)
    defer cancel()

    go func() {
        time.Sleep(cfg.Duration * time.Second)
        cancel()
    }()

    for {
        if atomic.LoadInt32(&currConnections) < atomic.LoadInt32(&maxConnections) - 1 {
            go httpPost(ctx, cfg, &ar)
        }

        select {
        // some other cases ...
        case <-ctx.Done():
            fmt.Printf("%d seconds have elapsed. Shutting down!", cfg.Duration)
            return
        }
    }
}

func httpPost(ctx context.Context, cfg AttackConfig, a *attackResponse) {
    // some code here to create HTTP client ...

    for {
        // some code to make HTTP call ...

        select {
        case <-ctx.Done():
            return
        default:
        }
    }
}

Avec cette modification, lorsque la cfg.Duration spécifiée expire, le canal ctx.Done() est fermé, signalant l'annulation des Goroutines httpPost(), qui seront alors retour.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn