Heim > Backend-Entwicklung > Golang > Wie kann ich Goroutinen nach einem bestimmten Zeitlimit in Go ordnungsgemäß abbrechen?

Wie kann ich Goroutinen nach einem bestimmten Zeitlimit in Go ordnungsgemäß abbrechen?

Mary-Kate Olsen
Freigeben: 2024-11-19 19:25:03
Original
814 Leute haben es durchsucht

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

Abbrechen von Goroutinen nach einem Zeitlimit

In Lasttestszenarien ist die Kontrolle der Ausführungsdauer von Goroutinen von entscheidender Bedeutung. Hier ist ein effektiver Ansatz, um dies zu erreichen.

Bedenken Sie den folgenden Codeausschnitt, der HTTP-Anfragen in Goroutinen verwaltet:

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
        }
    }
}
Nach dem Login kopieren

Goroutinen von httpPost() werden jedoch nach der angegebenen cfg.Duration weiter ausgeführt ist abgelaufen.

Um dieses Problem zu beheben, können Sie das Kontextpaket von Go nutzen. Indem Sie ein context.Context-Objekt an Ihre Goroutinen übergeben, können Sie diese Goroutinen abbrechen, wenn das angegebene Zeitlimit erreicht ist.

Hier ist eine überarbeitete Version Ihres Codes mit dem Kontextpaket:

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:
        }
    }
}
Nach dem Login kopieren

Mit dieser Änderung wird der ctx.Done()-Kanal geschlossen, wenn die angegebene cfg.Duration abläuft, was den Abbruch der httpPost()-Goroutinen signalisiert, die dann zurückkehren.

Das obige ist der detaillierte Inhalt vonWie kann ich Goroutinen nach einem bestimmten Zeitlimit in Go ordnungsgemäß abbrechen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage