libuv具有中央事件循环,并允许围绕它的异步网络I / O,计时器等。
文档中介绍的高级架构师是:
当事件循环为“就绪”套接字阻塞时(使用epoll等),如果没有一个套接字就绪,它将如何解除阻塞呢?它可能会错过一些可能在此期间用完的计时器。
如果如果没有一个套接字为空,并且没有计时器可触发而立即解除阻塞,那么事件循环是否会退化为“忙于等待”套接字准备就绪?
答案 0 :(得分:0)
uv_run
通过将额外的超时参数传递给轮询功能来确保不忙于等待。在Windows上,用于计算轮询呼叫超时的实现基本上像这样
int uv__next_timeout(const uv_loop_t* loop) {
const struct heap_node* heap_node;
const uv_timer_t* handle;
uint64_t diff;
/* If not timer block indefinitely */
heap_node = heap_min(timer_heap(loop));
if (heap_node == NULL)
return -1;
/* Timer should have fired already */
handle = container_of(heap_node, uv_timer_t, heap_node);
if (handle->timeout <= loop->time)
return 0;
/* Timer fires in the future, compute the timeout until the
next timer should fire */
diff = handle->timeout - loop->time;
if (diff > INT_MAX)
diff = INT_MAX;
return (int) diff;
}
仅当没有可用的计时器时,循环才会阻塞,直到准备好使用套接字/ IO完成端口为止,否则循环将最多阻塞直到下一次超时触发。 heap_min
确保始终返回下一个计时器,不会错过任何计时器。