Come funziona un thread dormiente?

7

Quando dormi un thread, cosa sta succedendo?

Vedo che dormire un thread "mette in pausa il thread corrente per un determinato periodo di tempo" . Ma come funziona?

Secondo How Thread.sleep () funziona internamente e Come funziona Thread.sleep? :

  • la durata del sonno sarà soggetta a granularità specifica del sistema
  • sleep è blocco
  • il thread lascia la CPU e interrompe l'esecuzione
  • il thread non consuma tempo della CPU durante la sospensione

Non riesco proprio a capire la meccanica interna e fondamentale di ciò che questo significa.

Capisco che ci sia qualcosa chiamato scheduler che è responsabile del passaggio da un thread all'altro.

Le fonti sembrano indicare che questo varia a seconda del sistema operativo (o dell'hardware?) e alla maggior parte dei thread viene assegnato 1 ms - 60 ms circa per eseguire alcune azioni prima che la CPU passi a un altro thread.

Ma quando un thread dorme (ad esempio, molti secondi), come si riprende? Immagino che un timer sia coinvolto in qualche modo, è l'orologio della scheda madre? È correlato al clock rate della CPU?

E anche se è coinvolto un timer, come fa la CPU a sapere quando è il momento di prestare nuovamente attenzione al thread? Non dovrebbe controllare costantemente sul thread per vedere se è pronto? In realtà non è eseguire il polling e quindi kinda-of è che consuma il tempo della CPU?

Dormire un thread specifico della lingua o il sistema operativo è responsabile di esso o è una cosa specifica della CPU?

Qualcuno potrebbe spiegarmi spiegazioni di base su cose come lo schedulatore e cosa sta facendo la CPU durante tutto questo?

    
posta Rowan Freeman 17.08.2016 - 08:16
fonte

2 risposte

7

C'è molto più coinvolgimento nell'esecuzione di un programma rispetto al solo codice all'interno di quel programma.

Qualsiasi programma eseguito in un sistema multi-processo è sotto il controllo del scheduler del sistema operativo e lo scheduler mantiene una tabella esplicita che dice quale processo è in esecuzione, quali sono in attesa di essere eseguiti quando I cicli della CPU sono disponibili e non si sta nemmeno tentando di eseguire (dormire). Lo scheduler assegna tipicamente intervalli di tempo di dimensioni pari ai processi in base alla loro priorità e alla loro cronologia di esecuzione. In definitiva, questo ciclo è guidato da interruzioni hardware, generalmente generate da un oscillatore sulla scheda madre.

Dormire è sempre una funzionalità che un linguaggio di programmazione può supportare solo perché l'ambiente di runtime in cui verrà eseguito lo supporta. Un normale programma non può sospendere se stesso , può solo dire allo schedulatore come dovrebbe come essere trattato - e lo scheduler non è obbligato o è sempre in grado di soddisfarlo desiderio. Pensa a un laptop chiuso e in letargo; l'oscillatore della scheda principale continua a pulsare, ma poiché lo scheduler non è in esecuzione, nessun processo può essere eseguito indipendentemente dalla sua priorità.

    
risposta data 17.08.2016 - 08:26
fonte
5

Come Doc Brown menzionato in un commento, gli interrupt sono la chiave, e non solo per dormire.

Un interrupt è un segnale hardware che il processore dovrebbe interrompere ciò che sta facendo ed eseguire un pezzo di codice. I dispositivi esterni attivano gli interrupt quando hanno bisogno dell'attenzione del processore: ad esempio, quando un disco ha terminato la lettura dei dati o è stato premuto un tasto o un timer per il conto alla rovescia sulla scheda madre ha raggiunto lo zero.

Il codice di gestione degli interrupt è generalmente molto piccolo e molto veloce. Ad esempio, quando il disco indica che un blocco è stato copiato in memoria, il sistema operativo potrebbe semplicemente registrare quel fatto in un elenco di "blocchi pronti" da qualche parte e quindi tornare a qualsiasi altra cosa stia facendo. Non vuoi che la CPU passi tutto il suo tempo nel codice di gestione degli interrupt e non esegua il codice utente.

Un pezzo di codice basato su interrupt che non è necessariamente piccolo è lo schedulatore. Viene attivato da un segnale proveniente da un timer per il conto alla rovescia ed esamina lo stato del sistema ogni volta che viene eseguito. Ciò in genere include l'identificazione dei processi che sono pronti per essere eseguiti (ad esempio, poiché il blocco che stavano aspettando è arrivato in memoria), così come quelli che hanno esaurito la loro fetta di tempo.

Quindi, quando esegui un thread in sleep, quello che stai facendo è dire al sistema operativo che (1) stai rinunciando al tuo time slice, e (2) non dovresti essere risvegliato fino a quando un certo tempo trascorso.

Ogni volta che lo scheduler viene eseguito, controlla il thread e lo contrassegna come "pronto per l'esecuzione" solo se è trascorso il tempo. Questo è il polling, di un tipo, ma non è il polling "busy-loop" poiché è attivato da un'interruzione. Non è nemmeno così costoso: in genere ci sono solo un migliaio di thread in esecuzione alla volta.

Questo dovrebbe anche darti un'idea del perché i tempi di sonno non sono esatti: quando il tuo thread è pronto per essere eseguito, potrebbero esserci altri thread che sono ancora in esecuzione e che non hanno esaurito la loro porzione di tempo. Oppure potrebbero esserci thread con priorità più alta che sono pronti per essere eseguiti.

    
risposta data 17.08.2016 - 13:20
fonte