根据我在这里所读的内容,golang调度程序将自动确定goroutine是否在I / O上阻塞,并将自动切换为在未阻塞的线程上处理其他goroutine。
我想知道的是调度程序如何确定该goroutine已停止阻止I / O。
它是否只是经常进行某种轮询以检查其是否仍处于阻塞状态?是否运行某种后台线程来检查所有goroutine的状态?
例如,如果要在需要5s的goroutine中执行HTTP GET请求,则它会在等待响应时阻塞,调度程序将切换为处理另一个goroutine。既然如此,当服务器返回响应时,调度程序如何理解响应已经到达,现在该回到创建GET的goroutine以便处理GET结果的时候了?
所有I / O必须通过syscall来完成,并且在Go中实现syscall的方式总是通过运行时控制的代码来调用。这意味着,当您调用syscall时,而不是直接调用它(从而放弃了对内核线程的控制),而是将您要进行的syscall通知运行时,并以goroutine的名义进行了调用。例如,这允许它执行非阻塞的系统调用,而不是阻塞的系统调用(本质上是告诉内核,“请执行此操作,而不是阻塞直到完成,立即返回,并在结果返回时让我知道准备好了”)。这使它可以在此期间继续进行其他工作。