我正在努力更好地理解网络库中的设计决策.信誉良好的来源在github问题和使用非阻塞套接字的邮件列表响应中提及network
.他们使用select来阻止,直到套接字准备好被读取,而不是使用默认的阻塞行为.为什么这样更好?无论哪种方式,它最终都会阻塞,并且network
只向最终用户公开阻止API.我的猜测是,阻止FFI调用是不好的,并且存在某种GHC魔法select
,但我无法证实这一点.
作为未成年人之外,我找不到地方select
在叫network
.打顶代码库没有出现任何问题.我刚刚发现了GHC.Event,它似乎提供了可以用来代替select
直接调用的函数,但是grepping shownetwork
也没有使用它.
非阻塞IO事件循环是GHC运行时系统(RTS)的一部分.这与GHC的绿色线程系统非常好地交互:不是编写异步代码,而是使用轻量级线程,运行时将负责唤醒正确的线程.
默认情况下,Haskell中的所有IO都是非阻塞的,所以如果你有两个线程在不同的套接字上被阻塞,那么运行时系统将在内部执行select
(或者某些其他特定于平台的方式来等待多个文件描述符)喜欢epoll
或kqueue
)只在文件描述符准备就绪时唤醒线程.有关详细信息,请参阅https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/IOManager.