From: https://www.mobibrw.com/2016/3490

libuv 是重写了下libev,封装了windows和unix的差异性。
libuv的特点
非阻塞TCP套接字 socket?
非阻塞命名管道
UDP
定时器
子进程 fork?
通过 uv_getaddrinfo实现异步DNS
异步文件系统API uv_fs_*
高分辨率时间 uv_hrtime
正在运行程序路径查找 uv_exepath
线程池调度 uv_queue_work
TTY控制的ANSI转义代码 uv_tty_t
文件系统事件支持 inotify ReadDirectoryChangesW kqueue 马上回支持 uv_fs_event_t
进程间的IPC与套接字共享 uv_write2

事件驱动的风格:程序关注/发送事件,在事件来临时给出反应。
系统编程中,一般都是在处理I/O,而IO的主要障碍是网络读取,在读取的时候是阻塞掉的。标准的解决方案是使用多线程,每一个阻塞的IO操作被分配到一个线程。当线程block,处理器调度处理其他线程。
libuv使用了另一个方案,异步。操作系统提供了socket的事件,即使用socket,监听socket事件即可。

libuv简单使用 创建一个loop,关闭loop。
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

int main()
{
uv_loop_t *loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);

printf("hello, libuv");

uv_run(loop, UV_RUN_DEFAULT);

uv_loop_close(loop);
free(loop);

return 0;
}

如果只需要一个loop的话,调用uv_default_loop就可以了。
tips:Nodejs中使用了这个loop作为主loop。
uv_loop_t *loop = uv_default_loop();

uv_run(loop, UV_RUN_DEFAULT);

uv_loop_close(loop);

Error
初始化或同步函数,会在执行失败是返回一个负数,可以通过uv_strerror、uv_err_name获得这个错误的名字和含义
I/O函数的回调函数会被传递一个nread参数,如果nread小于0,也代表出现了错误。

Handle & Request
libuv的工作建立在事件的监听上,通常通过handle来实现,handle中uv_TYPE_t中的type指定了handle监听的事件。
在uv.h中可以找到handle和request的定义
/* Handle types. */
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tcp_s uv_tcp_t;
typedef struct uv_udp_s uv_udp_t;
typedef struct uv_pipe_s uv_pipe_t;
typedef struct uv_tty_s uv_tty_t;
typedef struct uv_poll_s uv_poll_t;
typedef struct uv_timer_s uv_timer_t;
typedef struct uv_prepare_s uv_prepare_t;
typedef struct uv_check_s uv_check_t;
typedef struct uv_idle_s uv_idle_t;
typedef struct uv_async_s uv_async_t;
typedef struct uv_process_s uv_process_t;
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_fs_poll_s uv_fs_poll_t;
typedef struct uv_signal_s uv_signal_t;

/* Request types. */
typedef struct uv_req_s uv_req_t;
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_getnameinfo_s uv_getnameinfo_t;
typedef struct uv_shutdown_s uv_shutdown_t;
typedef struct uv_write_s uv_write_t;
typedef struct uv_connect_s uv_connect_t;
typedef struct uv_udp_send_s uv_udp_send_t;
typedef struct uv_fs_s uv_fs_t;
typedef struct uv_work_s uv_work_t;

/* None of the above. */
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;

handle是持久化的对象。在异步操作中,相应的handle有许多关联的request。
request是短暂性的,通常只维持一个回调的时间,一般对应handle的一个IO操作。request用来在初始函数和回调函数中传递上下文。
例如uv_udp_t代表了一个udp的socket,每一个socket的写入完成后,都有一个uv_udp_send_t被传递。

handle的设置
uv_TYPE_init(uv_loop_t*, uv_TYPE_t);

一个idle handle的使用例子 观察下它的生命周期
#include <stdio.h>
#include <uv.h>

int counter = 0;

void wait_for(uv_idle_t * handle)
{
counter++;

if (counter > 10e6)
{
uv_idle_stop(handle);
}
}

int main()
{
uv_idle_t idler;

uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for);

printf("Idle......");

uv_run(uv_default_loop(), UV_RUN_DEFAULT);

uv_loop_close(uv_default_loop());

return 0;
}

参数传递
handle和request都有一个data域,用来传递信息。uv_loop_t也有一个相似的data域。

文件系统
简单的文件读写是通过uv_fs_*函数族和与之相关的uv_fs_t结构体完成的。
系统的文件操作是阻塞的,所以libuv在线程池中调用这些函数,最后通知loop。

如果没有指定回调函数,文件操作是同步的,return libuv error code。
异步在传入回调函数时调用,return 0。

获得文件描述符
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb);
关闭文件描述符
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
回调函数
void callback(uv_fs_t* req);
还有uv_fs_read uv_fs_write uv_fs_t构成了基本的文件操作

流操作使用uv_stream_t,比基本操作方便不少
uv_read_start uv_read_stop uv_write
流操作可以很好的配合pipe使用
pipe相关函数
uv_pipe_init uv_pipe_open uv_close

文件事件
uv_fs_event_t uv_fs_event_init uv_fs_event_start

网络
uv_ip4_addr ip为 0.0.0.0表示绑定所有接口 255.255.255.255是一个广播地址,意味着数据将往所有的子网接口发送,端口号0表示由操作系统随机分配一个端口
tcp
TCP是面向连接的字节流协议,因此基于libuv的stream实现
uv_tcp_t
服务器端创建流程
uv_tcp_init 建立tcp句柄
uv_tcp_bind 绑定
uv_listen 建立监听,当有新的连接到来时,激活调用回调函数
uv_accept 接收链接
使用stream处理数据以及与客户端通信

客户端
客户端比较简单,只需要调用uv_tcp_connect

udp
UDP是不可靠连接,libuv基于uv_udp_t和uv_udp_send_t
udp的流程与tcp类似

libuv提供了一个异步的DNS解决方案,提供了自己的getaddrinfo
配置好主机参数addrinfo后使用uv_getaddrinfo即可

调用uv_interface_addresses获得系统的网络信息

未完待续。

来源:http://luohaha.github.io/Chinese-uvbook/source/introduction.html

[libuv] libuv学习相关推荐

  1. linux libuv,libuv queue的实现

    最近看node源码的时候注意到libuv中的一个队列实现,是c风格的,也是linux内核中常见的写法,因为一直使用c++的队列,所以对这种写法看不太懂,经过向牛人请教,终于明白了其中奥妙. 先一窥芳容 ...

  2. [libuv] libuv安装

    环境: centos7.2, gcc,g++ version: 4.8.5 yum install -y libuv libuv-devel

  3. 【libuv高效编程】libuv学习超详细教程1——libuv的编译与安装

    文章目录 libuv简介 下载libuv 安装必要的依赖 拉取libuv源码 编译使用 验证编译安装是否完成 简单实用 libuv简介 libuv 是一个高性能的,事件驱动的I/O,并且支持多平台的网 ...

  4. linux下编译libuv,linux下libuv库安装教程

    下载并编译libuv libuv需要自己手动下载源码,并手动编译. 当前目录为:/home/xlz/test/github/,在后面,会用$PATH来代替,我的系统的Debian8,64bit. $g ...

  5. Libuv的安装及运行使用

    Libuv的安装及运行使用 Libuv的官网链接:http://libuv.org/ GitHub下载链接:https://github.com/libuv/libuv CMake下载链接:https ...

  6. libuv 高性能 事件驱动 跨平台 i/o库 简介

    目录 1.Introduction 简介 Who this book is for Background Code 2.Basics of libuv libuv基础 Event loops HELL ...

  7. linux libuv 交叉编译 高性能事件驱动库

    1.由于需要热插拔功能,所以 libuv 需要链接 udev 库,下面是 eudev 的交叉编译 eudev 下载地址:https://github.com/gentoo/eudev 解压,执行: . ...

  8. [Nodejs原理] 核心库Libuv入门(Hello World篇)

    Libuv是什么? 1. 简介 Libuv是一个高性能的,事件驱动的异步I/O库,它本身是由C语言编写的,具有很高的可移植性.libuv封装了不同平台底层对于异步IO模型的实现,所以它还本身具备着Wi ...

  9. libuv udp server和client

    libuv libuv是nodejs异步的io库,并非仅仅是网络,还包括文件,我们使用该库的异步通信机制来制作udp的server和client. 在windows平台上要包含一些lib 1 发送方 ...

最新文章

  1. svn“Previous operation has not finished; run 'cleanup' if it was interrupted“报错的解决方法
  2. 最好用的 IntelliJ 插件 Top 10
  3. Java实体类对象修改日志记录
  4. python代码打开可执行文件_将自己的Python代码打包成exe文件(更换设备可运行的)...
  5. 好久没敲代码了(强行补上今天的博客。。。)
  6. 7-5 列车厢调度 (25 分)
  7. PTA12、 统计文字中的单词数量并按出现次数排序 (10 分)
  8. 分布式技术追踪 2018年第二期
  9. vue 项目难点_Vue 项目里戳中你痛点的问题及解决办法
  10. HTML知识积累及实践(四) - 表单元素
  11. 第10章 评价分类结果 学习笔记中
  12. 树莓派安装OpenCV2教程 (详细教程)
  13. python支持wps_Linux上使用python调用WPS二次开发接口
  14. origin作功率谱图
  15. 小招喵喜欢吃喵粮(贪心、二分查找)
  16. 攻防世界 Reverse高手进阶区 2分题 reverse-for-the-holy-grail-350
  17. iphone7刷入linux,iPhone7怎么进入DFU模式 iPhone7刷机步骤【详解】
  18. linux下解压iso镜像文件方法
  19. R语言使用cph函数和rcs函数构建限制性立方样条cox回归模型、检验模型是否满足等比例风险、是否存在非线性关系、使用rms包的Predict函数计算指定连续变量和风险比HR值的关系并可视化
  20. B站 马士兵Python 入门基础版 - 课程笔记

热门文章

  1. eclipse4.3.1标准版安装freemarker插件
  2. 中小企业如何提高售前,售中,售后客服质量?
  3. 艾伟:ASP.NET跨页面传值技巧总结
  4. 讯闪菜单密码去除方法
  5. 旧金山字体_旧金山建筑业的兴衰。 施工趋势与历史
  6. 编写程序乘法口诀表C语言,陈广川问:c语言编程九九乘法口诀表 怎样用c语言写九九乘法口诀表?...
  7. linux中gradle编译慢,【Linux】解决linux下android studio用gradle构建从jcenter或maven下载依赖太慢...
  8. leetcode950. 按递增顺序显示卡牌
  9. react 图像识别_无法在React中基于URL查找图像
  10. 在ASP.NET Atlas中调用Web Service——创建Mashup调用远端Web Service(基础知识以及简单示例)...