Heim  >  Artikel  >  Backend-Entwicklung  >  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
Mary-Kate OlsenOriginal
2024-11-19 19:25:03743Durchsuche

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
        }
    }
}

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:
        }
    }
}

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!

Stellungnahme:
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