Hallittu alasajo
Pysäytä työtekijät siististi
Hallittu alasajo on ilmainen Go Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Go Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Go Academy-kurssilla on yhteensä 4 oppituntia.
Miksi hallittu sammutus
Pitkään suoritettaville goroutineille on ilmoitettava, milloin niiden pitää lopettaa. Hallittu sammutus antaa workereille mahdollisuuden viimeistellä nykyisen työnsä, vapauttaa resurssit ja lopettaa ilman vuotoja tai datan menetystä.
- Ei goroutine-vuotoja
- Ei puolivalmiita kirjoituksia
- Prosessi päättyy siististi
done-kanavamalli
Perinteinen lähestymistapa on done-kanava. Sen sulkeminen lähettää pysäytyssignaalin kaikille sitä kuunteleville goroutineille, koska suljetusta kanavasta vastaanottaminen palautuu heti.
done := make(chan struct{})
// ... later
close(done)select pysäytyssignaaleille
Worker käyttää select-rakennetta joko työn käsittelyyn tai done-kanavan havaitsemiseen. Kun done suljetaan, kyseinen haara aktivoituu ja worker palaa.
for {
select {
case <-done:
return
case j := <-jobs:
process(j)
}
}context.Context
Idiomatic moderni työkalu on context. context.WithCancel antaa kontekstin ja peruutusfunktion. Kun cancel-funktiota kutsutaan, kontekstin Done-kanava suljetaan.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()Kuunteleminen kanavassa ctx.Done()
Workerit valitsevat toiminnon kanavan ctx.Done() perusteella. Kun cancel-funktiota kutsutaan tai määräaika umpeutuu, kanava suljetaan ja worker lopettaa.
select {
case <-ctx.Done():
return ctx.Err()
case j := <-jobs:
process(j)
}Workereiden odottaminen
Pysäytyssignaalin lähettäminen ei riitä, vaan workereiden todellista valmistumista on odotettava. sync.WaitGroup seuraa workereita, joten main voi estyä, kunnes laskuri saavuttaa nollan.
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
runWorker(ctx)
}()
// ... later
cancel()
wg.Wait()Aikakatkaisut contextilla
context.WithTimeout peruuttaa kontekstin automaattisesti määräajan kuluttua. Näin voidaan rajoittaa sitä, kuinka kauan sammutus saa kestää ennen pakotettua lopettamista.
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()Täydellinen hallittu sammutus
Tämä ohjelma suorittaa kahta workeria, peruuttaa kontekstin ja odottaa molempien siistiä lopettamista ennen kuin tulostaa 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")
}Käynnissä olevan työn viimeistely
Sammutuksen yhteydessä workerien halutaan usein viimeistelevän jo aloittamansa työ. Lukekaa jäljellä olevat työt viimeisessä silmukassa tai lopettakaa uusien töiden vastaanottaminen ja antakaa nykyisten töiden valmistua.
Käyttöjärjestelmäsignaalien käsittely
Oikeissa palvelimissa signal.NotifyContext yhdistää peruutuksen signaaleihin SIGINT ja SIGTERM. Ctrl+C:n painaminen käynnistää tällöin saman hallitun polun kuin manuaalinen peruutus.
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()Älkää unohtako cancel()-kutsua
Käyttäkää aina defer cancel()-komentoa myös WithTimeoutia käytettäessä. Jos cancel-kutsua ei tehdä, kontekstin sisäinen goroutine ja ajastin vuotavat, kunnes määräaika umpeutuu.
Pikatesti
Testatkaa hallittua sammutusta koskevat tietonne.
Kertaus
Opitte hallitun sammutuksen:
- Käyttäkää context.WithCancelia tai done-kanavaa pysäytyssignaalin lähettämiseen
- Workerit valitsevat toiminnon kanavan ctx.Done() perusteella
- WaitGroup varmistaa, että kaikki workerit todella lopettavat
- Yhdistäkää peruutus käyttöjärjestelmän signaaleihin oikeissa palvelimissa
- Käyttäkää aina defer cancel()
Opi Go tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 51
- Oppitunnit
- 203
Usein kysytyt kysymykset
Onko oppitunti ”Hallittu alasajo” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Go Academy-oppimispolun 3 oppituntia, myös oppitunnin “Hallittu alasajo”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Go Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Hallittu alasajo”?
Pysäytä työtekijät siististi Harjoittelet Go Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Go Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Go Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Hallittu alasajo”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Go Academy-oppitunnilla?
Kyllä. Jokainen Go Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Työtekijäpoolimalli
- Fan-out ja fan-in
- Putken vaiheet
- Hallittu alasajo