【发布时间】:2018-11-07 18:58:44
【问题描述】:
我正在尝试了解非阻塞网络 IO 在Node.js/libuv 中的工作方式。我已经发现 file IO 是使用 libuv 工作线程完成的(因此,在后台线程中)。然而,在很多地方都指出 network IO 是使用 epoll、kqueue 等系统调用以非阻塞方式完成的(取决于操作系统)。
现在我想知道这是否意味着实际的 IO 部分 (read())仍然在主线程上完成,因此阻塞,即使 e。 G。使用epoll?至于我的理解,epoll 仅通知可用事件,但实际上并不进行读/写。至少在我发现的示例中(例如http://davmac.org/davpage/linux/async-io.html)epoll 总是与read 系统调用结合使用,这是一个阻塞 IO 操作。
换句话说,如果libuv 使用单线程并且epoll 在数据可供读取时收到通知,那么接下来的读取操作会在主线程上执行,因此可能会阻塞其他操作(考虑网络请求)在主线程上?
【问题讨论】:
-
其实epoll有两种模式,一般我们使用数据到达时只触发一次用户的模式,所以我们需要把socket设置成非阻塞模式。
-
Socket 处于非阻塞模式意味着
readsyscall 在没有数据可用时不会阻塞。那么实际的 IO 还没有在后台某处完成? -
epoll/poll/select 都是用来对一个准备好做无阻塞操作的fd做IO操作。使用 poll/epoll/select 你可以在单个线程上使用阻塞操作进行异步操作。
-
@user826955 "所以实际的 IO 还没有在后台某处完成?"你的意思是 ? read 是实际的 IO。
-
好吧,正如我在上面试图解释的那样,我的理解(这可能是错误的)是
epoll的返回值将指示数据是否可用,而随后的read()实际上将从套接字读取字节。现在与libuv/Node.js相关,如果不是在单独的线程中完成,这个异步怎么办?
标签: c node.js networking io libuv