异步I/O库-libuv介绍

异步I/O库-libuv介绍libuv 是一个跨平台的支持事件驱动的异步 I O 的库 使开发者可以以非阻塞的方式执行文件 I O 操作 网络通信 子进程管理等

大家好,欢迎来到IT知识分享网。

1.简介

libuv是一个跨平台的支持事件驱动的异步I/O的库,使开发者可以以非阻塞的方式执行文件I/O操作、网络通信、子进程管理等。

libuv的主要特点包括:

  • 事件循环:libuv有一个基于事件循环的模型,它不断地轮询事件,并在事件发生时调用相应的回调函数。
  • 异步I/O:libuv提供了异步文件I/O和网络I/O的接口,使得开发者可以执行I/O操作而不阻塞主线程。
  • 线程池:libuv使用线程池来处理一些不能以非阻塞方式执行的I/O操作,如文件系统操作在某些操作系统上。
  • DNS解析:libuv提供了异步DNS解析的接口。
  • 高分辨率时钟:libuv提供了高精度的时间测量接口。

libuv的使用通常涉及以下几个步骤:

  • 初始化:使用uv_loop_init初始化事件循环。
  • 创建句柄:根据需要创建相应的句柄,如TCP句柄、UDP句柄等。
  • 启动事件循环:使用uv_run启动事件循环。
  • 关闭句柄:在不再需要句柄时,使用uv_close关闭句柄。
  • 清理资源:在程序结束时,使用uv_loop_close清理事件循环。

2.常用接口介绍

uv_loop_t – 事件循环

  • uv_loop_init(uv_loop_t*):初始化一个事件循环。
  • uv_run(uv_loop_t*,uv_run_mode):开始运行事件循环。uv_run_mode 可以是 UV_RUN_DEFAULT、UV_RUN_ONCE 或UV_RUN_NOWAIT。
  • uv_loop_close(uv_loop_t*):关闭事件循环并释放相关资源。

uv_handle_t – 句柄基类

  • uv_handle_size(uv_handle_type):返回特定类型句柄的大小。
  • uv_close(uv_handle_t*, uv_close_cb):关闭一个句柄并释放资源。当句柄关闭完成后,会调用
    uv_close_cb 回调函数。

uv_tcp_t – TCP 句柄

  • uv_tcp_init(uv_loop_t*, uv_tcp_t*):初始化一个 TCP 句柄。
  • uv_tcp_bind(uv_tcp_t*, const struct sockaddr*, unsigned int):将 TCP句柄绑定到指定的地址和端口。
  • uv_tcp_connect(uv_connect_t*, uv_tcp_t*, const struct sockaddr*, uv_connect_cb):异步连接到服务器。连接成功或失败时会调用 uv_connect_cb 回调函数。

uv_udp_t – UDP 句柄

  • uv_udp_init(uv_loop_t*, uv_udp_t*):初始化一个 UDP 句柄。
  • uv_udp_bind(uv_udp_t*, const struct sockaddr*, unsigned int):将 UDP句柄绑定到指定的地址端口。
  • uv_udp_recv_start(uv_udp_t*, uv_alloc_cb,uv_udp_recv_cb):开始接收 UDP 数据。uv_alloc_cb 用于分配接收缓冲区,uv_udp_recv_cb用于处理接收到的数据。

uv_timer_t – 定时器

  • uv_timer_init(uv_loop_t*, uv_timer_t*):初始化一个定时器。
  • uv_timer_start(uv_timer_t*, uv_timer_cb, uint64_t,uint64_t):启动定时器。uv_timer_cb 是定时器超时时的回调函数,uint64_t 参数指定第一次超时时间和重复间隔。
  • uv_timer_stop(uv_timer_t*):停止定时器。

uv_work_t – 工作线程

  • uv_queue_work(uv_loop_t*, uv_work_t*, uv_work_cb,
    uv_after_work_cb):将工作推送到 libuv 的线程池中执行。uv_work_cb
    是在线程池中执行的工作函数,uv_after_work_cb 是工作完成后在事件循环线程中调用的回调函数。

uv_process_t – 进程

  • uv_spawn(uv_loop_t*, uv_process_t*, constuv_process_options_t*):创建一个新进程。
  • uv_process_kill(uv_process_t*, int):发送信号到进程。

uv_fs_t – 文件系统操作

  • uv_fs_open(uv_loop_t*, uv_fs_t*, const char*, int, int,uv_fs_cb):异步打开文件。
  • uv_fs_read(uv_loop_t*, uv_fs_t*, uv_file, const uv_buf_t*, unsigned int, int64_t, uv_fs_cb):异步读取文件。
  • uv_fs_write(uv_loop_t*, uv_fs_t*, uv_file, const uv_buf_t*, unsigned int, int64_t, uv_fs_cb):异步写入文件。

3.环境搭建

4.示例

TCP服务端:

#include <iostream> #include <string> extern "C" { 
    #include "uv.h" } void on_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { 
    buf->base = (char*)malloc(suggested_size); buf->len = suggested_size; } void on_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) { 
    if (nread < 0) { 
    // 如果读取错误或连接已关闭,释放内存并关闭客户端 uv_close((uv_handle_t*)client, NULL); free(buf->base); return; } std::string message = "Hello, World!\n"; uv_write_t* req = (uv_write_t*)malloc(sizeof(uv_write_t)); uv_buf_t wrbuf = uv_buf_init((char*)message.c_str(), message.length()); uv_write(req, client, &wrbuf, 1, [](uv_write_t* req, int status) { 
    free(req); if (status < 0) { 
    std::cerr << "Write error: " << uv_strerror(status) << std::endl; } }); // 释放内存 free(buf->base); } void on_new_connection(uv_stream_t* server, int status) { 
    if (status < 0) { 
    std::cerr << "New connection error: " << uv_strerror(status) << std::endl; return; } uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); uv_tcp_init(uv_default_loop(), client); if (uv_accept(server, (uv_stream_t*)client) == 0) { 
    uv_read_start((uv_stream_t*)client, on_alloc, on_read); } else { 
    uv_close((uv_handle_t*)client, NULL); } } int main() { 
    uv_tcp_t server; uv_tcp_init(uv_default_loop(), &server); struct sockaddr_in addr; uv_ip4_addr("0.0.0.0", 8080, &addr); uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0); int r = uv_listen((uv_stream_t*)&server, 128, on_new_connection); if (r) { 
    std::cerr << "Listen error: " << uv_strerror(r) << std::endl; return 1; } std::cout << "Listening on port 8080..." << std::endl; uv_run(uv_default_loop(), UV_RUN_DEFAULT); return 0; } 

TCP客户端:

void on_connect(uv_connect_t* req, int status) { 
    if (status < 0) { 
    std::cerr << "Connect error: " << uv_strerror(status) << std::endl; return; } // 连接成功,发送数据 uv_stream_t* stream = req->handle; std::string message = "Hello, Server!\n"; uv_write_t* write_req = (uv_write_t*)malloc(sizeof(uv_write_t)); uv_buf_t buf = uv_buf_init((char*)message.c_str(), message.length()); uv_write(write_req, stream, &buf, 1, [](uv_write_t* req, int status) { 
    free(req); if (status < 0) { 
    std::cerr << "Write error: " << uv_strerror(status) << std::endl; } }); } void on_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) { 
    if (nread < 0) { 
    // 如果读取错误或连接已关闭,释放内存并关闭客户端 uv_close((uv_handle_t*)client, NULL); free(buf->base); return; } // 打印接收到的数据 std::cout.write(buf->base, nread); // 释放内存 free(buf->base); } int main() { 
    uv_tcp_t* socket = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); uv_tcp_init(uv_default_loop(), socket); struct sockaddr_in dest; uv_ip4_addr("127.0.0.1", 8080, &dest); uv_connect_t* connect_req = (uv_connect_t*)malloc(sizeof(uv_connect_t)); uv_tcp_connect(connect_req, socket, (const struct sockaddr*)&dest, on_connect); // 开始读取数据 uv_read_start((uv_stream_t*)socket, [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { 
    buf->base = (char*)malloc(suggested_size); buf->len = suggested_size; }, on_read); std::cout << "Connecting to server..." << std::endl; uv_run(uv_default_loop(), UV_RUN_DEFAULT); // 清理资源 free(socket); free(connect_req); return 0; } 

5.更多参考

libVLC 专栏介绍-CSDN博客

Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍_qt opengl视频播放器-CSDN博客

QCharts -1.概述-CSDN博客

网络库-libevent介绍

网络库-libcurl介绍

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/111143.html

(0)
上一篇 2026-01-26 20:15
下一篇 2026-01-26 20:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信