2016-04-08 25 views
5

Da quello che ho letto here, lo scheduler golang determinerà automaticamente se una goroutine sta bloccando l'I/O e passerà automaticamente all'elaborazione di altre goroutine su un thread che non è bloccato.Quando una goroutine blocca su I/O, in che modo lo scheduler identifica che ha smesso di bloccare?

Quello che mi chiedo è come lo scheduler capisca che quella goroutine ha smesso di bloccare l'I/O.

Fa semplicemente qualche tipo di polling ogni tanto per controllare se sta ancora bloccando? Esiste una sorta di thread in background in esecuzione che controlla lo stato di tutte le goroutine?


Per esempio, se si dovesse fare una richiesta HTTP GET all'interno di un goroutine che ha preso 5s per ottenere una risposta, avrebbe bloccato durante l'attesa per la risposta, e lo scheduler sarebbe passare ad un'altra elaborazione goroutine. Ora dato che, quando il server restituisce una risposta, in che modo lo scheduler capisce che la risposta è arrivata, ed è ora di tornare alla goroutine che ha fatto il GET in modo che possa elaborare il risultato del GET?

risposta

8

Tutti gli I/O devono essere eseguiti tramite le sysc e il modo in cui i sysc vengono implementati in Go, vengono sempre chiamati attraverso il codice controllato dal runtime. Ciò significa che quando chiamate un syscall, invece di chiamarlo direttamente (rinunciando quindi al controllo del thread sul kernel), il runtime viene avvisato del syscall che volete creare, e lo fa per conto della goroutine. Ciò consente, ad esempio, di eseguire un syscall non bloccante invece di uno bloccante (essenzialmente dicendo al kernel, "per favore fai questa cosa, ma invece di bloccare finché non è fatto, torna immediatamente, e fammi sapere più tardi una volta che il risultato è pronta"). Ciò gli consente di continuare a svolgere altri lavori nel frattempo.

+1

Penso di aver già capito questa parte. Ciò di cui sono davvero curioso è come questa parte "fammi sapere più tardi una volta che il risultato è stato letto" sia stata eseguita. Come controlla se "il risultato è letto" – m0meni

+0

Solitamente usando un segnale. Quindi alcune funzioni particolari che specificate verranno chiamate dal kernel quando l'IO è fatto e quella funzione può gestirlo come vuole. – joshlf

+0

Ma come fai a sapere che l'IO è fatto? Capisco la nozione di una richiamata, ma come si può capire se l'operazione di I/O è completata come nell'esempio che ho aggiunto sopra a una richiesta GET. – m0meni