当goroutine阻塞I/O时,调度程序如何识别它已停止阻塞?

m0m*_*eni 7 concurrency multithreading go

从我在这里读到的,golang调度程序将自动确定goroutine是否在I/O上阻塞,并将自动切换到处理未阻塞的线程上的其他goroutine.

我想知道的是调度程序然后如何确定goroutine已停止阻止I/O.

它是否经常进行某种轮询以检查它是否仍然阻塞?是否有某种后台线程运行检查所有goroutines的状态?


例如,如果您在goroutine中执行HTTP GET请求需要5s才能获得响应,它会在等待响应时阻塞,并且调度程序将切换到处理另一个goroutine.现在假设,当服务器返回响应时,调度程序如何理解响应已经到达,是时候回到构成GET的goroutine,以便它可以处理GET的结果?

jos*_*hlf 9

所有I/O必须通过系统调用完成,并且在Go中实现syscalls的方式,它们总是通过运行时控制的代码调用.这意味着当你调用一个系统调用时,而不是直接调用它(从而放弃对内核的线程控制),运行时会收到你想要的系统调用通知,并代表goroutine执行.例如,这允许它执行非阻塞系统调用而不是阻塞系统调用(基本上告诉内核,"请执行此操作,但不要阻塞直到完成,立即返回,并在结果后告诉我准备好了").这允许它在此期间继续做其他工作.