libuv事件循环
1、说明
事件循环是 libuv 的核心功能,负责 IO 的轮询和事件回调的调度。
2、数据类型
2.1、uv_loop_t
事件循环数据类型,结构体
uv_loop_t.data 用于传递用户数据,libuv 不会触碰
2.2、uv_walk_cb
传递给 uv_walk() 方法的回调函数类型
void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
3、API
3.1、uv_loop_init
int uv_loop_init(uv_loop_t* loop);
初始化 uv_loop_t 结构体
要注意,调用之前需要先给 uv_loop_t 分配内存资源,否则会崩溃
3.2、uv_loop_configure
int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...);
设置事件循环配置,一般应该在第一次调用 uv_run() 之前执行
返回值: 0表示成功,错误则返回一个 UV_E 错误码,UV_ENOSYS 表示平台不支持该事件循环配置
支持选项:
- UV_LOOP_BLOCK_SIGNAL :轮询新事件时阻塞指定事件,uv_loop_configure 的第二个参数是信号编号;
- UV_METRICS_IDLE_TIME :在事件的提供者的事件循环中收集空闲时间,使用 uv_metrics_idle_time() 方法需要使用这个选项
3.3、uv_loop_close
int uv_loop_close(uv_loop_t* loop);
释放所有内部循环资源
仅当所有循环完成并且所有打开的句柄和请求都已经关闭的时候才可调用此函数,否则将返回 UV_EBUSY
此函数返回后,用户可以释放为循环申请的内存
3.4、uv_default_loop
uv_loop_t* uv_default_loop(void);
返回 libuv 的默认事件循环,如果分配失败了,可能返回NULL
这个方法是在整个应用程序中进行全局循环的一个便捷的方式,和自定义的事件循环相同
3.5、uv_run
int uv_run(uv_loop_t* loop, uv_run_mode mode);
运行事件循环,mode 指定运行模式,有如下几种:
- UV_RUN_DEFAULT :运行事件循环,知道没有活动的和被引用的句柄和请求。如果使用 uv_stop() 方法终止还未停止的循环(仍然有活动的和被引用的句柄和请求),则返回值非0,其他情况下返回0;
- UV_RUN_ONCE :只进行一次 IO 口轮询,如果没有需要执行的回调函数,这个方法会阻塞,返回0表示完成(没有活动的和被引用的句柄和请求),返回非0表示需要进行更多的回调(此时,需要再次进行事件循环);
- UV_RUN_NOWAIT :和 UV_RUN_ONCE 的区别是,不会阻塞;
uv_run() 方法是不可重入的,它不能作为回调函数被调用
3.6、uv_loop_alive
int uv_loop_alive(const uv_loop_t* loop);
判断事件循环是否还在活动,返回非0表示还在活动
有以下几种情况之一表示还在活动:
- 有被引用的活动句柄或者活动请求;
- 正在关闭的句柄;
3.7、uv_stop
void uv_stop(uv_loop_t* loop);
停止事件循环,会让 uv_run() 方法尽快结束
该方法调用之后,下次事件循环迭代之前结束循环,正在进行的事件循环仍然继续
如果该函数在 IO 阻塞之前执行,则在当前的事件迭代中, IO 不会被阻塞
3.8、uv_loop_size
size_t uv_loop_size(void);
返回 uv_loop_t 结构体 size
3.9、uv_backend_fd
int uv_backend_fd(const uv_loop_t* loop);
获取后端文件描述符,仅使用于 kqueue、epoll 和 事件端口
该方法可以和 run(loop, UV_RUN_NOWAIT) 一起联合使用,在一个线程中轮询 IO 和处理回调
3.10、uv_backend_timeout
int uv_backend_timeout(const uv_loop_t* loop);
获取 IO 轮询超时时间,单位为毫秒,没有超时时返回 -1
3.11、uv_now
uint64_t uv_now(const uv_loop_t* loop);
返回当前的时间戳,单位毫秒
时间戳在事件循环开始时缓存
3.12、uv_update_time
void uv_update_time(uv_loop_t* loop);
更新事件循环的时间戳,会影响 uv_now() 的返回值,libuv 会在事件循环开始时缓存当前时间,以减少系统的时间相关的方法的调用
通常情况下不需要调用此方法,除了事件循环中的某个回调会阻塞相当长的时间,这个所谓的相当长的时间是有些主观的,可能是一毫秒或者更长
3.13、uv_walk
void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg);
遍历句柄列表,执行回调
arg 参数会传递给回调函数
void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
handle 为遍历中的某个句柄
3.14、uv_loop_fork
int uv_loop_fork(uv_loop_t* loop);
在调用 fork(2) 之后,如果有必要,在子进程中重新初始化内核状态
在子进程中以观察者的身份继续事件循环
如果你想继续在子进程中使用事件循环,包括默认的事件循环(尽管不想在父进程中使用它),那么,在每个父进程中创建的事件循环中显示地调用此方法是很有必要的
该方法必须在 uv_run() ,或者其他想要在子进程中调用其他API之前调用。如果不这样做,可将将导致一些未知的错误,比如事件被重复交给父进程和子进程,或者子进程异常退出
可以的话,最好在子进程中创建一个新的循环,而不是重复使用父进程创建的循环。在 fork 子进程之后,并在子进程中创建的新的循环不应该使用此方法
该方法不适用于windows操作系统,他会返回 UV_ENOSYS
需要注意的是,该方法可能存在BUG
3.15、uv_loop_get_data
void* uv_loop_get_data(const uv_loop_t* loop);
返回 loop->data
3.16、uv_loop_set_data
void* uv_loop_set_data(uv_loop_t* loop, void* data);
设置 loop->data 的值
libuv事件循环的更多相关文章
- libuv事件循环中的三种句柄
1.说明 本文会简单介绍 libuv 的事件循环,旨在入门级别的使用,而不做深入探究,简单来说就是,会大概用就行,先用熟练了,再去探究原理和源码 下图为官网的 libuv 的不同部分及其涉及的子系统的 ...
- node源码详解(六) —— 从server.listen 到事件循环
本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource6 本博客同步在https://cnodejs.o ...
- Node.js 事件循环(Event Loop)介绍
Node.js 事件循环(Event Loop)介绍 JavaScript是一种单线程运行但又绝不会阻塞的语言,其实现非阻塞的关键是“事件循环”和“回调机制”.Node.js在JavaScript的基 ...
- node 事件循环
什么是事件循环 Node只运行在一个单一线程上,至少从Node.js开发者的角度是这样的.在底层, Node是通过libuv来实现多线程的. Libuv库负责Node API的执行.它将不同的任务分配 ...
- [译] 所有你需要知道的关于完全理解 Node.js 事件循环及其度量
原文地址:All you need to know to really understand the Node.js Event Loop and its Metrics 原文作者:Daniel Kh ...
- nodejs事件循环
1. 只有一个主线程,node开始执行脚本时,会先进事件循环初始化(同步任务,发出异步请求,规划定时器生效时间,执行promise.nextTick等),这是事件循环还未开始. 2. nodejs每一 ...
- Node.js 事件循环机制
Node.js 采用事件驱动和异步 I/O 的方式,实现了一个单线程.高并发的 JavaScript 运行时环境,而单线程就意味着同一时间只能做一件事,那么 Node.js 如何通过单线程来实现高并发 ...
- 浏览器与Node的事件循环(Event Loop)有何区别?
前言 本文我们将会介绍 JS 实现异步的原理,并且了解了在浏览器和 Node 中 Event Loop 其实是不相同的. 一.线程与进程 1. 概念 我们经常说 JS 是单线程执行的,指的是一个进程里 ...
- js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)
javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...
随机推荐
- Win Docker 安装C盘清理方法之一
背景 由于Docker默认安装到C盘,C盘空间越发的小了,虽然(win10)C盘满了并不会很大影响,但是强迫症患者是不能忍得 解决办法 查询https://stackoverflow.com/ques ...
- MFC3 基本对话框的使用(三) 滑块与进度条(sdnu)(C++大作业)
一.完成界面 运行前: 运行后: 二.工具 (1)滑块 (2)进度条 (3)文本框 (4)文本示例 (5)按钮 三.添加变量 四.添加事件 右键单击主对话框空白部分,打开类向导,选择"消息& ...
- .NET Core 处理 WebAPI JSON 返回烦人的null为空
前言 项目开发中不管是前台还是后台都会遇到烦人的null,数据库表中字段允许空值,则代码实体类中对应的字段类型为可空类型Nullable<>,如int?,DateTime?,null值字段 ...
- TCP/IP五层模型-应用层-DNS协议
1.定义:域名解析协议,把域名解析成对应的IP地址. 2.分类:①迭代解析:DNS所在服务器若没有可以响应的结果,会向客户机提供其他能够解析查询请求的DNS服务器地址,当客户机发送查询请求时,DNS ...
- maven生命周期与插件
目录 Maven生命周期 clean default site 命令与对应周期 插件与绑定 插件目标 插件绑定 内置绑定 自定义绑定 插件配置 本文主要是针对<maven实战>书中关键知识 ...
- win10/windows 安装Pytorch
https://pytorch.org/get-started/locally/ 去官网,选择你需要的版本. 把 pip install torch==1.5.0+cu101 torchvision= ...
- zabbix自定义监控nginx
nginx配置ngx_status 1.编译安装时带上--with-http_stub_status_module参数 2.vi nginx.conf location ~* ^/ngx_status ...
- RSA共模攻击
在安恒月赛中碰到一道密码学方向的ctf题 附上源码 from flag import flag from Crypto.Util.number import * p=getPrime(1024) q= ...
- mysql查看修改参数
1.查看参数 show variables like '%timeout%'; 2.修改参数 会话级别修改: set session innodb_lock_wait_timeout=50; 对当前会 ...
- Java高并发与多线程(三)-----线程的基本属性和主要方法
今天,我们开始Java高并发与多线程的第三篇,线程的基本属性和主要方法. [属性] 编号(ID) 类型long 用于标识不同的线程,编号唯一,只存在java虚拟机的一次运行 名称(Name) 类型St ...