Go Academy · Lezione

Limitare le goroutine

Controllare la concorrenza

Lezione 3 di 413 passaggi

Limitare le goroutine è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.

Limitare la concorrenza

A volte non si limita il numero di operazioni al secondo, ma il numero di goroutine eseguite contemporaneamente. In questo modo si limita il carico simultaneo su una risorsa, indipendentemente dalla temporizzazione.

  • Limita il parallelismo
  • Protegge i pool di connessioni
  • Previene i picchi di utilizzo della memoria

Il canale semaforo

Un canale con buffer funziona come un semaforo a conteggio. La sua capacità corrisponde alla concorrenza massima. L'acquisizione invia un token; il rilascio ne riceve uno.

sem := make(chan struct{}, 3)

Acquisizione e rilascio

Prima di avviare il lavoro, invii un valore nel canale per acquisire uno slot (l'operazione si blocca se il canale è pieno). Al termine, riceva un valore per rilasciarlo e rendere lo slot disponibile per un'altra goroutine.

sem <- struct{}{}        // acquire
// do work
<-sem                    // release

Perché usare struct{}

Una struct vuota struct{}{} occupa zero byte. Usarla come tipo degli elementi del canale trasforma il semaforo in un puro segnale, senza sprechi di memoria.

Limitare un ciclo

Avvii una goroutine per ogni attività, ma la vincoli al semaforo. Al massimo cap goroutine eseguono contemporaneamente il lavoro effettivo; le altre si bloccano durante l'acquisizione.

for _, task := range tasks {
    sem <- struct{}{}
    go func(t Task) {
        defer func() { <-sem }()
        process(t)
    }(t)
}

Combinazione con WaitGroup

Il semaforo limita la concorrenza, ma non indica quando tutto il lavoro è terminato. Lo combini con un sync.WaitGroup per attendere il completamento di tutte le attività.

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    defer func() { <-sem }()
    process(t)
}()

Rilasciare in defer

Rilasci sempre lo slot in un defer, così viene liberato anche se il lavoro causa un panic o restituisce il controllo in anticipo. Dimenticare il rilascio esaurisce gli slot e alla fine causa il deadlock dei nuovi acquirenti.

Un'esecuzione completa con limitazione

Questo programma esegue otto attività con al massimo due attività contemporaneamente e stampa l'inizio e la fine per mostrare il limite in azione.

package main

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

func main() {
    sem := make(chan struct{}, 2)
    var wg sync.WaitGroup
    for i := 0; i < 8; i++ {
        wg.Add(1)
        sem <- struct{}{}
        go func(id int) {
            defer wg.Done()
            defer func() { <-sem }()
            fmt.Println("start", id)
            time.Sleep(20 * time.Millisecond)
            fmt.Println("end", id)
        }(i)
    }
    wg.Wait()
    fmt.Println("done")
}

errgroup con SetLimit

Il pacchetto golang.org/x/sync/errgroup offre SetLimit per limitare un gruppo e propagare il primo errore. In molti casi è un'alternativa più pulita, anche se è un pacchetto esterno.

Limitazione o worker pool

Un worker pool riutilizza un insieme fisso di goroutine che prelevano attività da una coda. La limitazione tramite semaforo avvia una goroutine per ogni attività, ma limita quelle attive. I pool sono più efficienti con un numero enorme di attività; i semafori sono più semplici da aggiungere.

Scegliere il limite

Per le chiamate al database, imposti il limite a un valore pari o inferiore alla dimensione del pool di connessioni. Per le richieste HTTP in uscita, lo adegui al limite di connessioni dell'host. Un valore troppo alto esaurisce le risorse; uno troppo basso spreca capacità.

Verifica rapida

Verifichi la Sua conoscenza della limitazione della concorrenza.

Riepilogo

Ha imparato a limitare le goroutine:

  • Un canale con buffer funziona come un semaforo a conteggio
  • Si acquisisce inviando e si rilascia ricevendo in defer
  • Gli elementi di tipo struct{} occupano zero byte
  • Lo si combina con WaitGroup per attendere il completamento
  • Si dimensiona il limite in base alla risorsa protetta
Gratis per iniziare

Impara Go con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
51
Lezioni
203

Domande Frequenti

La lezione «Limitare le goroutine» è gratuita?

Sì — il testo completo di «Limitare le goroutine» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.

Cosa imparerò in «Limitare le goroutine»?

Controllare la concorrenza Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Go Academy?

Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Limitare le goroutine»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Go Academy?

Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Concetto del token bucket
  2. golang.org/x/time/rate
  3. Limitare le goroutine
  4. Backoff e retry
← Torna a Go Academy