为什么 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 魔法,但我无法证实这一点。
作为未成年人,我找不到 select
在 network
中调用的地方。 Grepping 代码库没有发现任何东西。我刚刚发现 GHC.Event,它似乎提供了可以用来代替直接调用 select
的函数,但是 grepping 显示 network
也没有使用它。
non-blocking IO 事件循环是 GHC 运行时系统 (RTS) 的一部分。这与 GHC 的绿色线程系统交互得非常好:不用编写异步代码,您可以只使用轻量级线程,运行时将负责唤醒正确的线程。
默认情况下,Haskell 中的所有 IO 都是 non-blocking,因此如果您有两个线程,每个线程都阻塞在不同的套接字上,那么运行时系统将在内部执行 select
(或其他一些 platform-specific 等待多个文件描述符的方法,如 epoll
或 kqueue
)仅在文件描述符准备就绪时唤醒线程。有关详细信息,请参阅 https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/IOManager。
我试图更好地理解 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 魔法,但我无法证实这一点。
作为未成年人,我找不到 select
在 network
中调用的地方。 Grepping 代码库没有发现任何东西。我刚刚发现 GHC.Event,它似乎提供了可以用来代替直接调用 select
的函数,但是 grepping 显示 network
也没有使用它。
non-blocking IO 事件循环是 GHC 运行时系统 (RTS) 的一部分。这与 GHC 的绿色线程系统交互得非常好:不用编写异步代码,您可以只使用轻量级线程,运行时将负责唤醒正确的线程。
默认情况下,Haskell 中的所有 IO 都是 non-blocking,因此如果您有两个线程,每个线程都阻塞在不同的套接字上,那么运行时系统将在内部执行 select
(或其他一些 platform-specific 等待多个文件描述符的方法,如 epoll
或 kqueue
)仅在文件描述符准备就绪时唤醒线程。有关详细信息,请参阅 https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/IOManager。