2016-04-08 10 views
5

Von dem, was ich here gelesen habe, wird der Golang Scheduler automatisch feststellen, ob eine Goroutine auf I/O blockiert, und wird automatisch zur Verarbeitung anderer Goroutines auf einem Thread, der nicht blockiert ist, wechseln.Wenn eine Goroutine bei E/A blockiert, wie erkennt der Scheduler, dass er nicht mehr blockiert?

Was ich frage mich ist, wie der Scheduler dann herausfindet, dass diese Goroutine auf I/O blockiert gestoppt hat.

Macht es nur eine Art von Abfragen, um zu überprüfen, ob es immer noch blockiert? Gibt es eine Art Hintergrund Thread, der den Status aller goroutines überprüft?


Zum Beispiel, wenn Sie eine HTTP-GET-Anforderung in einem goroutine zu tun sind, die 5s nahm eine Antwort zu bekommen, wäre es zu blockieren, während für die Antwort zu warten, und der Planer wechseln würde eine andere goroutine zu verarbeiten. Nun, wenn der Server eine Antwort zurückgibt, wie weiß der Scheduler, dass die Antwort angekommen ist, und es Zeit ist, zu der Goroutine zurückzukehren, die das GET gemacht hat, damit es das Ergebnis des GET verarbeiten kann?

Antwort

8

Alle I/O müssen über syscalls erfolgen, und die Art, wie syscalls in Go implementiert wird, wird immer durch Code aufgerufen, der von der Laufzeit gesteuert wird. Das heißt, wenn Sie einen Syscall aufrufen, anstatt ihn direkt aufzurufen (und somit die Kontrolle über den Thread an den Kernel abgeben), wird die Runtime über den von Ihnen gewünschten Syscall benachrichtigt, und zwar im Auftrag der Ganoutine. Dies ermöglicht es zum Beispiel, einen nicht blockierenden Syscall anstelle eines blockierenden zu tun (im Wesentlichen dem Kernel zu sagen, "bitte mach das Ding, aber statt zu blockieren, bis es fertig ist, sofort zurückkehren, und lass mich später einmal das Ergebnis wissen ist bereit"). Dies ermöglicht es, andere Arbeiten in der Zwischenzeit fortzusetzen.

+1

Ich glaube, ich habe diesen Teil schon verstanden. Worüber ich wirklich neugierig bin, ist, wie dieser Teil "mich später wissen lassen wird, sobald das Ergebnis gelesen wurde". Wie überprüft es, ob "das Ergebnis gelesen wird" – m0meni

+0

Normalerweise ein Signal verwenden. Eine bestimmte Funktion, die Sie angeben, wird also vom Kernel aufgerufen, wenn die IO fertig ist und diese Funktion damit umgehen kann, wie sie will. – joshlf

+0

Aber woher wissen Sie, dass die IO gemacht wird? Ich verstehe die Idee eines Rückrufs, aber wie können Sie herausfinden, ob die IO-Operation abgeschlossen ist, wie in dem Beispiel, das ich oben über eine GET-Anfrage hinzugefügt habe. – m0meni

Verwandte Themen