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