yjhjstz/deep-into-node

关于uv__io_poll的一些疑问

hyj1991 opened this issue · 5 comments

在uv_run函数中
I/O部分调用的uv__io_poll,这一块libuv做了跨平台
我看的是Mac下的kqueue.c这个文件,然后有一个小小的疑问:
nfds = kevent(loop->backend_fd,
events,
nevents,
events,
ARRAY_SIZE(events),
timeout == -1 ? NULL : &spec);
第一个疑问是:
当有请求到达服务器时,kevent被唤醒,此时如果因为之前的loop耗时较多导致已经有3个请求积压在kqueue中,那么这里的nfds就等于3吗?
也就是说,这种情况下,在当前这次loop中实际上处理了三个已经到达的请求。
第二个疑问是:
如果是的话,那这三个到达的请求的回调处理是按照达到kqueue的顺序被循环执行的么?

顺着您的书籍加上自己的一些源码阅读,看到这边其实有点疑惑
以http服务器为例,假如每一个请求处理句柄都平均花费20ms
那么如果真正的10000个并发,单进程意味着最后的一个请求要最理想也要等待200s才能被处理
即使开启四个cluster的子进程,那么最理想的情况下,也有会每个子进程最后分配到的四个请求要等待50s才能被处理
这样体验因该是相当之差的,那么以前Node号称的支持十万级别的并发,到底是怎么执行出来的,感觉越看底层代码越无法理解哇
是不是我对于这样的网络I/O请求执行逻辑理解有误呢?

Q1: nfds 代表多个准备好的请求。

Q2:

w = loop->watchers[fd];

由该连接的 fd 值决定,具体可以加打印确认下。

Q3: 确实有误
20ms 等待时间并不阻塞在主线程,而是由主线程分发到线程池处理,多路复用,所以不用排队等待200s。

Q1和Q2我又打印了下,大概明白了
Q3中,比如最简单的

http.createServer(function(req, res){
    //这里的同步业务逻辑花费了20ms
}).listen(8080);

这里的处理回调执行js花费的20ms是会阻塞在主线程的吧

比如业务代码是

fs.writeSync(xx);

那么,会阻塞主线程。

thx~我之前思考的陷入了一个误区,明白了