三年前libuv还是0.10版本时,公司项目的服务端网络层我用了libuv。今天准备将libuv作为当前新项目的网络底层库,发现曾经的api已大改。好在官方给了一份变动文档。
libuv 0.10 -> 1.0.0 migration guide
http://docs.libuv.org/en/v1.x/migration_010_100.html
Some APIs changed quite a bit throughout the 1.0.0 development process. Here is a migration guide for the most significant changes that happened after 0.10 was released.
Loop initialization and closing
In libuv 0.10 (and previous versions), loops were created with uv_loop_new, which allocated memory for a new loop and initialized it; and destroyed withuv_loop_delete, which destroyed the loop and freed the memory. Starting with 1.0, those are deprecated and the user is responsible for allocating the memory and then initializing the loop.
libuv 0.10
uv_loop_t* loop = uv_loop_new();
...
uv_loop_delete(loop);
libuv 1.0
uv_loop_t* loop = malloc(sizeof *loop);
uv_loop_init(loop);
...
uv_loop_close(loop);
free(loop);
Note
Error handling was omitted for brevity. Check the documentation for uv_loop_init()
and uv_loop_close()
.
Error handling
Error handling had a major overhaul in libuv 1.0. In general, functions and status parameters would get 0 for success and -1 for failure on libuv 0.10, and the user had to use uv_last_error to fetch the error code, which was a positive number.
In 1.0, functions and status parameters contain the actual error code, which is 0 for success, or a negative number in case of error.
libuv 0.10
... assume 'server' is a TCP server which is already listening
r = uv_listen((uv_stream_t*) server, 511, NULL);
if (r == -1) {
uv_err_t err = uv_last_error(uv_default_loop());
/* err.code contains UV_EADDRINUSE */
}
libuv 1.0
... assume 'server' is a TCP server which is already listening
r = uv_listen((uv_stream_t*) server, 511, NULL);
if (r < 0) {
/* r contains UV_EADDRINUSE */
}
Threadpool changes
In libuv 0.10 Unix used a threadpool which defaulted to 4 threads, while Windows used the QueueUserWorkItem API, which uses a Windows internal threadpool, which defaults to 512 threads per process.
In 1.0, we unified both implementations, so Windows now uses the same implementation Unix does. The threadpool size can be set by exporting theUV_THREADPOOL_SIZE
environment variable. See Thread pool work scheduling.
Allocation callback API change
In libuv 0.10 the callback had to return a filled uv_buf_t
by value:
uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
return uv_buf_init(malloc(size), size);
}
In libuv 1.0 a pointer to a buffer is passed to the callback, which the user needs to fill:
void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
buf->base = malloc(size);
buf->len = size;
}
Unification of IPv4 / IPv6 APIs
libuv 1.0 unified the IPv4 and IPv6 APIS. There is no longer a uv_tcp_bind and uv_tcp_bind6 duality, there is only uv_tcp_bind()
now.
IPv4 functions took struct sockaddr_in
structures by value, and IPv6 functions took struct sockaddr_in6
. Now functions take a struct sockaddr*
(note it’s a pointer). It can be stack allocated.
libuv 0.10
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", 1234);
...
uv_tcp_bind(&server, addr)
libuv 1.0
struct sockaddr_in addr;
uv_ip4_addr("0.0.0.0", 1234, &addr)
...
uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
The IPv4 and IPv6 struct creating functions (uv_ip4_addr()
and uv_ip6_addr()
) have also changed, make sure you check the documentation.
Streams / UDP data receive callback API change
The streams and UDP data receive callbacks now get a pointer to a uv_buf_t
buffer, not a structure by value.
libuv 0.10
void on_read(uv_stream_t* handle,
ssize_t nread,
uv_buf_t buf) {
...
}
void recv_cb(uv_udp_t* handle,
ssize_t nread,
uv_buf_t buf,
struct sockaddr* addr,
unsigned flags) {
...
}
libuv 1.0
void on_read(uv_stream_t* handle,
ssize_t nread,
const uv_buf_t* buf) {
...
}
void recv_cb(uv_udp_t* handle,
ssize_t nread,
const uv_buf_t* buf,
const struct sockaddr* addr,
unsigned flags) {
...
}
Receiving handles over pipes API change
In libuv 0.10 (and earlier versions) the uv_read2_start function was used to start reading data on a pipe, which could also result in the reception of handles over it. The callback for such function looked like this:
void on_read(uv_pipe_t* pipe,
ssize_t nread,
uv_buf_t buf,
uv_handle_type pending) {
...
}
In libuv 1.0, uv_read2_start was removed, and the user needs to check if there are pending handles using uv_pipe_pending_count()
and uv_pipe_pending_type()
while in the read callback:
void on_read(uv_stream_t* handle,
ssize_t nread,
const uv_buf_t* buf) {
...
while (uv_pipe_pending_count((uv_pipe_t*) handle) != 0) {
pending = uv_pipe_pending_type((uv_pipe_t*) handle);
...
}
...
}
Extracting the file descriptor out of a handle
While it wasn’t supported by the API, users often accessed the libuv internals in order to get access to the file descriptor of a TCP handle, for example.
fd = handle->io_watcher.fd;
This is now properly exposed through the uv_fileno()
function.
uv_fs_readdir rename and API change
uv_fs_readdir returned a list of strings in the req->ptr field upon completion in libuv 0.10. In 1.0, this function got renamed to uv_fs_scandir()
, since it’s actually implemented using scandir(3)
.
In addition, instead of allocating a full list strings, the user is able to get one result at a time by using the uv_fs_scandir_next()
function. This function does not need to make a roundtrip to the threadpool, because libuv will keep the list of dents returned by scandir(3)
around.
相关推荐
通过深入研究libuv 0.1版本,我们可以学习到如何构建高效、可扩展的异步应用,并且能够更好地理解Node.js背后的机制。尽管技术在不断进步,但libuv的基本设计原则——异步事件驱动、线程池以及平台无关性——仍然在...
- libuv在Windows下有一些特定的API和配置。例如,你需要确保`uv_loop_init`使用的是`uv_loop_new`而不是Unix版本。 - 在调试过程中,可能需要处理Windows特有的错误代码和事件。 通过以上步骤,你可以在CLion中...
### libuv API说明及用例知识点详解 #### 一、概述 **libuv** 是一个多平台支持库,其设计核心在于提供高效的异步 I/O 操作。最初为 Node.js 而开发,但随后也被其他项目如 Luvit、Julia 和 pyuv 等采用。该库的...
这可能涉及到禁用一些只在新版本Windows中存在的API。 步骤四:解决依赖问题 libuv可能依赖于一些XP不支持的库,如WS2_32.lib、Userenv.lib等。你需要检查并更新项目的链接器设置,确保链接到XP兼容的库版本。同时...
本资源在 debian 9 交叉编译器版本arm-linuxgnueabihf-gcc -v gcc version 6.3.0 20170516 (Debian 6.3.0-18) 下成功编译生成arm-linux下能运行的库,暂时编译成功还没进行测试,
1.22.0是libuv在2018年7月发布的版本,它提供了对多种操作系统(如Windows、Linux、macOS等)的支持,并且具有高度可移植性。 在Windows系统中,动态链接库(DLL)是一种可执行文件格式,它包含可供其他程序调用的...
《深入理解libuv库:基于libuv-1.39.0版本的探索》 libuv,一个跨平台的异步I/O库,是Node.js的核心组成部分,它为开发人员提供了一个高度抽象的接口,用于处理操作系统级别的网络和低级I/O操作。libuv的1.39.0版本...
总而言之,《libuv书中文文档:An introduction to libuv》为开发者提供了一个全面的学习路径,涵盖了从基础到高级的各种主题,帮助他们掌握libuv库的使用,从而构建出更加高效、可扩展的跨平台应用。
运行node ./release.js --version xxx --dir path --remote name ,其中xxx是您正在创建的libuv的版本, path是计算机上libuv核心存储库的位置, name是libuv核心git远程。 这将执行一些任务,例如在必要时更新...
1. **获取源码**:首先,你需要从 Libuv 的官方仓库或者第三方源下载 v1.33.1 版本的源代码,通常是一个名为 `libuv-v1.33.1.zip` 的压缩包。 2. **解压并打开项目**:将下载的压缩包解压,然后使用 VS2019 打开 `...
其次,在下载libuv源代码的环节,推荐使用wget工具直接从GitHub仓库下载特定版本的libuv源代码压缩包。这个版本被指定为v1.33.0,但在实际操作中应当检查是否有更新的版本。下载完毕后,需要对压缩包进行解压缩,这...
你需要将 Libuv 的 `uv_loop_t` 结构封装到类中,然后提供开始、停止循环的方法。同时,需要适配 Libuv 的事件回调,将它们转化为面向对象的事件处理。 5. **错误处理**:封装 Libuv 应该提供清晰的错误处理机制,...
2. **获取源码**:从官方仓库克隆或下载 LibUV v1.34.0 版本。 3. **配置构建**:使用 CMake 创建一个适用于 VS2019 的解决方案文件。指定生成动态链接库 (DLL) 并选择 64 位目标平台。 4. **编译构建**:打开生成...
libuv是一个基于C语言编写的高性能、事件驱动的I/O库,它提供了跨平台的API,支持如Windows、Linux等操作系统。libuv在设计上强调了事件驱动编程范式,其核心是提供一个event-loop(事件循环),以及基于I/O和其他...
5. **异步操作**:使用libuv提供的API进行异步操作,如`uv_connect`发起网络连接,`uv_fs_open`打开文件等。 6. **处理事件**:当相应的事件发生时,libuv会调用预先注册的回调函数,处理这些事件。 7. **结束和...
另外,虽然 libuv 自身没有内置的日志记录功能,但其 API 友好,可以方便地集成到第三方日志库中。 10. **API 设计** libuv 的 API 设计简洁且易于使用,遵循了 C 语言的习惯,使用回调函数处理异步结果,同时也...
libuv是一款由node.js核心团队开发的高性能、事件驱动的I/O库,它为开发者提供了一套跨平台的API,包括对文件系统、网络、进程、线程以及异步I/O操作的支持。libuv的API调用方式类似于Linux下的pthread,适用于需要...
“This ‘book’ is a small set of tutorials about using libuv [https://github.com/libuv/libuv] as a high performance evented I/O library which offers the same API on Windows and Unix. It is meant to ...
- **Node.js模块开发**:对于`node.js`模块的开发者来说,`libuv`提供了一种方法,可以将用C/C++编写的平台API封装成异步API,以便在`node.js`环境中使用。 - **注意**:虽然`libuv`是`node.js`的一部分,但其用途...
libuv是一个专注于高性能、事件驱动I/O的跨平台库,其主要特色在于为开发者提供了一套统一的事件循环机制,无论是在Windows还是Unix平台下,都能提供一致的API接口。libuv支持异步I/O操作,包括网络编程和文件系统...