libuv学习记录
发布于 9 年前 作者 showen 12665 次浏览 最后一次编辑是 8 年前 来自 分享

libuv是什么

官方介绍如下: libuv is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by Node.js, but it’s also used by Luvit, Julia,pyuv, and others.

进一步概述: libuv是一个高性能事件驱动库,屏蔽了各种操作系统的差异从而提供了统一的API。libuv严格使用异步、事件驱动的编程风格。其核心工作是提供事件循环及基于 I/O或其他活动事件的回调机制libuv库包含了诸如计时器、非阻塞网络支持、异步文件系统访问、线程创建、子进程等核心工具

libuv核心之“事件循环(Event loops)”

在libuv事件编程模型中, 应用程序只是去监视特定的事件, 并在事件发生后对其作出响应。而收集事件或监控其他事件源则是libuv的职责, 编程人员只需要对感兴趣的事件去注册回调函数, 在事件发生后 libuv 将会调用相应的回调函数. 只要程序不退出并且还有待处理的事件, 事件循环会一直运行, 下面是事件驱动编程模型的伪代码:

     while there are still events to process:
          e = get the next event
          if there is a callback associated with e:
              call the callback
最原始的一个libuv程序:
		#include <stdio.h>
		#include <uv.h>
		int main() {
			// uv_loop_t *loop = uv_loop_new();  //创建一个新的事件环
			uv_loop_t *loop = uv_default_loop();  //libuv默认的一个事件环,nodejs主线程用的就是默认的事件环
			printf("Now quitting.\n");
			
			//以默认模式(UV_RUN_DEFAULT)启动事件环,因为没有要监听的事件所以程序会直接退出
			uv_run(loop, UV_RUN_DEFAULT);
			return 0;
		}

libuv核心之“监视器(Watchers)”

libuv 通过监视器(Watcher)来对特定事件进行监控, 监视器通常是类似 uv_TYPE_t 结构体的封装, TYPE 代表该监视器的用途, libuv 一些常见的监视器类型如下:

		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_timer_s uv_timer_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;

所有监视器的结构都是 uv_handle_t 的”子类”。 另外uv_stream_t比较特殊,数据进行流操作要用到它。

监视器使用的简单的步骤:

一、首先要初始化监视器

      uv_TYPE_init(uv_loop_t*,uv_TYPE_t*)   //这样就把监视器和loop联系起来了

二、设置监视器的回调函数

       uv_TYPE_start(uv_TYPE_t*, callback)   
	   uv_TYPE_stop(uv_TYPE_t*)  //停止监听
   这只是其中一种形式,文件系统、网络操作等的设置回调函数是不一样的,但都是大同小异。之后会详细介绍的。另外各种监视器的回调函数带回来的参数是不一样的。

三、启动事件环

	   uv_run(loop, UV_RUN_DEFAULT);

一个监视‘空闲’的小例子:

		#include <stdio.h>
		#include <uv.h>
		
		int64_t counter = 0;
		void wait_for_a_while(uv_idle_t* handle, int status) {  //程序空闲的时候执行,**各种回调类型的参数不一样**
		  counter++;
		  if (counter >= 10e6)
		  uv_idle_stop(handle); //停止监听,事件环停止,程序停止
		}
		
		int main() {
		  uv_idle_t idler;
		
		  uv_idle_init(uv_default_loop(),&idle);  //初始化监视器
		  uv_idle_start(&idler, wait_for_a_while);  //设置监视器的回调函数
		
		  printf("Idling...\n");
		  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
		
		  return 0;
		}

未完待续,记录一下学习,我只是搬运工。有兴趣的同学可以看这里

7 回复

有一个learnlibuv的项目

@i5ting 我是看uvbook学习的,文章最后有链接,不知道你说的是这个不。

@fuckingcode 虽然是2年前的基于v1.3.x写的,但是考虑到目前libuv最新的稳定版也就v1.10.x,其实API变化并不大~设计思想更是几乎一致的

@hyj1991 赞同,个人还是感觉 uvbook 讲得更透彻些。

回到顶部