Go Academy · leksjon

Kontrollert avslutning

Stopp arbeidere ryddig

Leksjon 4 av 413 trinn

Kontrollert avslutning er en gratis leksjon i Go Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Go Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Go Academy inneholder totalt 4 leksjoner.

Hvorfor kontrollert avslutning

Gorutiner som kjører lenge, må få beskjed om når de skal stoppe. Kontrollert avslutning lar arbeiderne fullføre det pågående arbeidet, frigjøre ressurser og avslutte uten lekkasjer eller tapte data.

  • Ingen lekkasjer av gorutiner
  • Ingen halvferdige skrivinger
  • Ryddig avslutning av prosessen

Mønsteret med done-kanalen

En klassisk tilnærming er en done-kanal. Når den lukkes, kringkaster den et stoppsignal til alle gorutiner som lytter på den, fordi en lukket kanal returnerer umiddelbart ved mottak.

done := make(chan struct{})
// ... later
close(done)

select for stoppsignaler

En arbeider bruker select til enten å behandle en jobb eller oppdage done-kanalen. Når done lukkes, aktiveres denne grenen, og arbeideren returnerer.

for {
    select {
    case <-done:
        return
    case j := <-jobs:
        process(j)
    }
}

context.Context

Det idiomatiske moderne verktøyet er context. context.WithCancel gir Dem en kontekst og en cancel-funksjon. Når De kaller cancel, lukkes kontekstens Done-kanal.

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Lytte på ctx.Done()

Arbeiderne bruker select på ctx.Done(). Når cancel kalles eller en tidsfrist utløper, lukkes kanalen, og arbeideren avslutter.

select {
case <-ctx.Done():
    return ctx.Err()
case j := <-jobs:
    process(j)
}

Vente på arbeiderne

Det er ikke nok å signalisere stopp; De må vente på at arbeiderne faktisk blir ferdige. En sync.WaitGroup holder oversikt over dem, slik at main kan blokkeres til telleren når null.

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    runWorker(ctx)
}()
// ... later
cancel()
wg.Wait()

Tidsavbrudd med context

context.WithTimeout avbryter automatisk etter en gitt varighet. Dette setter en grense for hvor lenge avslutningen kan ta før De tvinger frem en avslutning.

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

En komplett kontrollert avslutning

Dette programmet kjører to arbeidere, avbryter konteksten og venter på at begge skal avslutte ryddig før det skriver ut done.

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func worker(ctx context.Context, id int, wg *sync.WaitGroup) {
    defer wg.Done()
    for {
        select {
        case <-ctx.Done():
            fmt.Printf("worker %d stopping\n", id)
            return
        case <-time.After(50 * time.Millisecond):
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    var wg sync.WaitGroup
    for i := 1; i <= 2; i++ {
        wg.Add(1)
        go worker(ctx, i, &wg)
    }
    time.Sleep(120 * time.Millisecond)
    cancel()
    wg.Wait()
    fmt.Println("all workers stopped")
}

Tømme arbeid som er under behandling

Ved avslutning ønsker De ofte at arbeiderne skal fullføre det de allerede har startet. Les gjenværende jobber i en siste løkke, eller slutt å ta imot nye jobber mens de pågående jobbene får fullføre.

Fange opp OS-signaler

I virkelige servere knytter signal.NotifyContext avbrytelse til SIGINT og SIGTERM. Når De trykker på Ctrl+C, utløses dermed den samme kontrollerte avslutningen som ved en manuell avbrytelse.

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

Glem aldri cancel()

Bruk alltid defer cancel(), også når De bruker WithTimeout. Hvis De ikke kaller cancel, lekker kontekstens interne gorutine og tidtaker frem til tidsfristen utløper.

Kort sjekk

Test kunnskapene Deres om avslutning.

Oppsummering

De har lært om kontrollert avslutning:

  • Bruk context.WithCancel eller en done-kanal for å signalisere stopp
  • Arbeiderne bruker select på ctx.Done()
  • WaitGroup sikrer at alle arbeiderne faktisk avslutter
  • Knytt avbrytelse til OS-signaler i virkelige servere
  • Bruk alltid defer cancel()
Gratis å komme i gang

Lær deg Go med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
51
Leksjoner
203

Ofte stilte spørsmål

Er leksjonen «Kontrollert avslutning» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Go Academy, inkludert «Kontrollert avslutning», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Go Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Kontrollert avslutning»?

Stopp arbeidere ryddig Du øver på Go Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Go Academy?

Ingen tidligere erfaring er nødvendig. Go Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «Kontrollert avslutning»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Go Academy-leksjonen?

Ja. Alle Go Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Worker pool-mønsteret
  2. Fan-out og fan-in
  3. Pipeline-steg
  4. Kontrollert avslutning
← Tilbake til Go Academy