We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libuv 最初是为 Node.js 所作的跨平台库。它基于事件驱动的异步 I/O 模型。
libuv 不仅仅只提供了对于不同 I/O 轮询机制的简单抽象:“句柄(handles)”和“流(streams)”也提供了对于 socket 和其他相关实例的高度抽象。同时 libuv 还提供了跨平台文件 I/O 接口和多线程接口等等。
下图展示了 libuv 的不同组成部分,以及与这些部分相关的子模块:
为了能使用户介入事件循环(event loop),libuv 为用户提供了两个抽象:句柄和请求。
句柄表示一个在其被激活时可以执行某些操作且持久存在的对象。例如:当一个预备句柄(prepare handle)处于激活时,它的回调函数会在每次事件循环中被调用;每当一个新 TCP 连接来到时,一个 TCP 服务器句柄的连接回调函数就会被调用。
请求(通常)表示一个短暂存在的操作。这些操作可以操作于句柄,例如写请求(write requests)用于向一个句柄写入数据。但是又如 getaddrinfo 请求则不依赖于一个句柄,它们直接在事件循环上执行。
事件循环是 libuv 的核心部分。它为所有的 I/O 操作建立了上下文,并且执行于一个单线程中。你可以在多个不同的线程中运行多个事件循环。除非另有说明,不然 libuv 的事件循环(以及其他循环或句柄提供的 API)并不是线程安全的。
事件循环遵循着普遍的单线程异步 I/O 行为:所有的(网络)I/O 体现在非阻塞的 socket 上,对于不同的平台,libuv 会选取最佳的轮询机制:Linux 上为 epoll ,OSX 和其他 BSD 上为 kqueue ,SunOS 上为 event ports , Windows 上则为 IOCP 。作为循环迭代的一部分,事件循环会阻塞并等待被添加的 socket 上 I/O 活动的发生。然后根据当前的 socket 情况(可读,可写,挂起)触发相应的回调函数。所以,一个句柄是可以执行读操作,写操作或其他 I/O 行为。
为了能更好的理解事件循环是如何工作的,下图展示了事件循环一次迭代的所有过程:
UV_RUN_NOWAIT
uv_stop()
uv_close()
UV_RUN_ONCE
uv_run()
UV_RUN_DEFAULT
重要:虽然 libuv 的异步文件 I/O 操作是通过线程池实现的,但是网络 I/O 总是在单线程中执行的。
注意:虽然在不同平台上使用的轮询机制不同,但 libuv 的执行模型在不同平台下都是保持一致。
与网络 I/O 不同,并不存在 libuv 可以依靠的各特定平台下的文件 I/O 基础函数,所以目前的实现是在线程中执行阻塞的文件 I/O 操作来模拟异步。
更多关于跨平台异步文件 I/O 操作的内容,可参阅此文。
libuv 目前使用了一个全局的线程池,所有的循环都可以往其中加入任务。目前有三种操作会在这个线程池中执行:
uv_queue_work()
注意:更多关于 libuv 线程池的信息请参阅此文。请牢记线程池的大小是有限的。
原文链接:http://docs.libuv.org/en/v1.x/design.html
The text was updated successfully, but these errors were encountered:
No branches or pull requests
概述
libuv 最初是为 Node.js 所作的跨平台库。它基于事件驱动的异步 I/O 模型。
libuv 不仅仅只提供了对于不同 I/O 轮询机制的简单抽象:“句柄(handles)”和“流(streams)”也提供了对于 socket 和其他相关实例的高度抽象。同时 libuv 还提供了跨平台文件 I/O 接口和多线程接口等等。
下图展示了 libuv 的不同组成部分,以及与这些部分相关的子模块:
句柄(handles)和请求(requests)
为了能使用户介入事件循环(event loop),libuv 为用户提供了两个抽象:句柄和请求。
句柄表示一个在其被激活时可以执行某些操作且持久存在的对象。例如:当一个预备句柄(prepare handle)处于激活时,它的回调函数会在每次事件循环中被调用;每当一个新 TCP 连接来到时,一个 TCP 服务器句柄的连接回调函数就会被调用。
请求(通常)表示一个短暂存在的操作。这些操作可以操作于句柄,例如写请求(write requests)用于向一个句柄写入数据。但是又如 getaddrinfo 请求则不依赖于一个句柄,它们直接在事件循环上执行。
事件循环
事件循环是 libuv 的核心部分。它为所有的 I/O 操作建立了上下文,并且执行于一个单线程中。你可以在多个不同的线程中运行多个事件循环。除非另有说明,不然 libuv 的事件循环(以及其他循环或句柄提供的 API)并不是线程安全的。
事件循环遵循着普遍的单线程异步 I/O 行为:所有的(网络)I/O 体现在非阻塞的 socket 上,对于不同的平台,libuv 会选取最佳的轮询机制:Linux 上为 epoll ,OSX 和其他 BSD 上为 kqueue ,SunOS 上为 event ports , Windows 上则为 IOCP 。作为循环迭代的一部分,事件循环会阻塞并等待被添加的 socket 上 I/O 活动的发生。然后根据当前的 socket 情况(可读,可写,挂起)触发相应的回调函数。所以,一个句柄是可以执行读操作,写操作或其他 I/O 行为。
为了能更好的理解事件循环是如何工作的,下图展示了事件循环一次迭代的所有过程:
UV_RUN_NOWAIT
标识执行,那么超时将会是 0 。uv_stop()
已在之前被调用),那么超时将会是 0 。uv_close()
被关闭,那么这将会调用关闭回调。UV_RUN_ONCE
标识执行,那么在这时这些超时的定时器的回调将会在此时得到执行。UV_RUN_NOWAIT
或UV_RUN_ONCE
标识执行,迭代便会结束,并且uv_run()
将会返回。如果循环以UV_RUN_DEFAULT
标识执行,那么如果若它还是存活的,它就会开始下一次迭代,否则结束。重要:虽然 libuv 的异步文件 I/O 操作是通过线程池实现的,但是网络 I/O 总是在单线程中执行的。
文件 I/O
与网络 I/O 不同,并不存在 libuv 可以依靠的各特定平台下的文件 I/O 基础函数,所以目前的实现是在线程中执行阻塞的文件 I/O 操作来模拟异步。
更多关于跨平台异步文件 I/O 操作的内容,可参阅此文。
libuv 目前使用了一个全局的线程池,所有的循环都可以往其中加入任务。目前有三种操作会在这个线程池中执行:
uv_queue_work()
添加的用户代码最后
原文链接:http://docs.libuv.org/en/v1.x/design.html
The text was updated successfully, but these errors were encountered: