为什么 haskell 的网络库使用非阻塞套接字?

Why does haskell's network library use non-blocking sockets?

我试图更好地理解 network library. Reputable sources mention in a github issue and a mailing list response that network uses non-blocking sockets. Instead of using the default blocking behavior, they use select 中做出的设计决定,即阻塞直到套接字准备好被读取。为什么这样更好?无论哪种方式,它最终都会阻塞,并且 network 只会向最终用户公开阻塞 API。我的猜测是 FFI 调用阻塞是不好的,并且 select 周围存在某种 GHC 魔法,但我无法证实这一点。

作为未成年人,我找不到 selectnetwork 中调用的地方。 Grepping 代码库没有发现任何东西。我刚刚发现 GHC.Event,它似乎提供了可以用来代替直接调用 select 的函数,但是 grepping 显示 network 也没有使用它。

non-blocking IO 事件循环是 GHC 运行时系统 (RTS) 的一部分。这与 GHC 的绿色线程系统交互得非常好:不用编写异步代码,您可以只使用轻量级线程,运行时将负责唤醒正确的线程。

默认情况下,Haskell 中的所有 IO 都是 non-blocking,因此如果您有两个线程,每个线程都阻塞在不同的套接字上,那么运行时系统将在内部执行 select(或其他一些 platform-specific 等待多个文件描述符的方法,如 epollkqueue)仅在文件描述符准备就绪时唤醒线程。有关详细信息,请参阅 https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/IOManager