Thread
Esecuzione concorrente
Thread è una lezione Ruby Academy gratuita su CoddyKit. Questa è la lezione 1 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 Ruby Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Ruby Academy include 4 lezioni in totale.
Che cos'è un thread?
Un thread è un percorso di esecuzione indipendente all'interno del programma. Ruby consente di eseguire più thread, così le attività possono sovrapporsi nel tempo.
- Il programma principale viene eseguito nel thread principale.
- Può creare altri thread con
Thread.new. - I thread condividono la stessa memoria, quindi possono leggere e modificare le stesse variabili.
I thread sono ideali quando il programma trascorre del tempo ad attendere (rete, disco, sleep), perché un thread può attendere mentre un altro continua a lavorare.
Creare un thread
Passi un blocco a Thread.new. Il blocco viene eseguito in un nuovo thread. Chiami join per attenderne il completamento prima che il programma termini.
t = Thread.new do
puts "Hello from the new thread"
end
t.join
puts "Main thread done"Perché join è importante
Quando il thread principale termina, Ruby esce e potrebbe non attendere gli altri thread. join blocca il chiamante finché il thread di destinazione non termina.
Senza join, il thread di lavoro potrebbe non avere mai l'opportunità di stampare il risultato prima che il programma termini.
t = Thread.new do
sleep 0.1
puts "Worker finished"
end
puts "Waiting..."
t.join
puts "All done"Più thread contemporaneamente
Può avviare un gruppo di thread, raccoglierli in un array e poi chiamare join su ciascuno di essi. Questo è un modello comune per le attività di I/O che possono essere eseguite quasi in parallelo.
threads = (1..3).map do |n|
Thread.new do
puts "Thread number " + n.to_s
end
end
threads.each(&:join)
puts "Finished all threads"Condividere le variabili
I thread condividono la memoria. Una variabile definita prima del thread è visibile al suo interno. Questo è potente, ma anche rischioso se due thread modificano lo stesso valore.
counter = 0
t = Thread.new do
counter += 1
end
t.join
puts "Counter is " + counter.to_sCondizioni di gara
Una condizione di gara si verifica quando i thread alternano gli aggiornamenti ai dati condivisi e il risultato dipende dalla tempistica.
counter += 1equivale in realtà a leggere, sommare e scrivere.- Due thread possono leggere lo stesso vecchio valore e scrivere entrambi lo stesso nuovo valore, perdendo così un incremento.
La soluzione consiste nel coordinare l'accesso tramite un lock.
Mutex: un lock
Un Mutex (esclusione reciproca) garantisce che, in un dato momento, un solo thread esegua il codice protetto. Racchiuda la sezione critica in mutex.synchronize.
mutex = Mutex.new
counter = 0
threads = (1..5).map do
Thread.new do
mutex.synchronize do
counter += 1
end
end
end
threads.each(&:join)
puts "Counter is " + counter.to_sRestituire un valore
Thread#value attende il completamento del thread e restituisce il valore del suo blocco, come una combinazione automatica di join e di un risultato.
t = Thread.new do
2 + 3
end
puts "Result is " + t.value.to_sVariabili locali al thread
Ogni thread può memorizzare i propri valori, indicizzati da un simbolo, con Thread.current[:key]. Questi valori sono privati del thread e non vengono mai condivisi.
t = Thread.new do
Thread.current[:name] = "worker"
puts "Inside: " + Thread.current[:name]
end
t.joinGestire le eccezioni
Se un thread solleva un errore, l'errore rimane silenzioso finché non chiama join o value, che lo sollevano nuovamente. Impostando Thread.abort_on_exception = true, gli errori causano immediatamente l'arresto dell'intero programma, facilitando il debugging.
t = Thread.new do
raise "boom"
end
begin
t.join
rescue => e
puts "Caught: " + e.message
endQuando i thread sono utili
I thread sono particolarmente efficaci per le attività vincolate all'I/O, in cui il tempo viene trascorso ad attendere. Sono meno utili per le attività vincolate alla CPU a causa del GVL, che verrà trattato nella prossima sezione.
- Ideali per: scaricare molti URL, leggere molti file.
- Limitati per: eseguire calcoli numerici intensivi su più core.
Protegga sempre lo stato mutabile condiviso con un Mutex.
Verifica rapida
Verifichi la sua comprensione dei thread.
Riepilogo: i thread
Ha appreso i concetti essenziali dei thread di Ruby:
Thread.newavvia l'esecuzione concorrente.joinattende;valueattende e restituisce un risultato.- I thread condividono la memoria, causando condizioni di gara.
- Un
Mutexconsynchronizeprotegge lo stato condiviso. - I thread sono particolarmente efficaci per le attività vincolate all'I/O.
Ora analizzeremo perché i thread non possono utilizzare completamente più core della CPU: il GVL.
Domande Frequenti
La lezione «Thread» è gratuita?
Sì — il testo completo di «Thread» è 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 Ruby Academy, passa a CoddyKit PRO. Il corso Ruby Academy include 4 lezioni in totale.
Cosa imparerò in «Thread»?
Esecuzione concorrente Eserciti Ruby 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 Ruby Academy?
Non è richiesta alcuna esperienza precedente. Ruby 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 1 di 4.
Quanto tempo richiede la lezione «Thread»?
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 Ruby Academy?
Sì. Ogni lezione Ruby 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.