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
Libérer: 2024-11-19 19:25:03
original
818 Les gens l'ont consulté

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
        }
    }
}
Copier après la connexion

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:
        }
    }
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal