libuv初学者学习笔记

简介: 开始阅读前,我简单的理解觉得是,类似于leetcode的一种题,外部同时启动开始,但是内部严格的按照线程1->线程2的顺序发生过程。

ibuv框架

50615a5f9de34bb4975a48e8de4b9dad.png

从上往下看,从左往右分成网络IO与文件IO等操作:网络I/O看,linux平台通过底层epoll作为异步I/O处理,中间是抽象层uv__io_t;对于文件I/O,linux没有特定平台的异步原语,所以在线性池中执行阻塞Io来实现异步。


同步I/O


由于与cpu处理速度不匹配,我们采用多线程多进程来执行,不会当一个进程挂起后影响其他线程或进程。但是存在弊端,系统不会无上限的增加线程/进程,并且切换线程的开销也不能忽略,所以多线程多进程切换时间会占用cpu运行代码时间,降低性能,所以引入异步I/O。

异步I/O

简单来说就是,用户不需要等待内核完成实际对io的读写操作就直接返回了。


异步 事件驱动


libuv提供一套事件循环和基于I/O通知的回调函数还有loop。

9277848f584a4d0b901c6e2c4ff7fd0c.png


libuv提供的核心工具->计时器、非阻塞网络编程(tcp)、异步访问文件系统……

loops:职责:收集事件或监控其它事件。

事件驱动编程,程序会关注事件,对于每个事件产生反应。

上图就是所有I/O事件循环处理的过程,即uv_run()函数执行过程。


1.首先判断循环是否活着,通过是否存在alive活动状态的句柄,不存在则退出。

2.开始倒计时,维护所有的定时器,若句柄超时就告知应用层,退出或者重新加入循环。

3.调用待处理的回调函数,如果有待处理的就去处理它。

4.运行空闲句柄。

5.运行准备回调句柄,在某个I/O要阻塞前,有需要的话就运行回调函数。

6.计算轮询超时,在阻塞I/O前循环会计算阻塞时间,并将I/O进入阻塞状态。


规则(先留印象,后理解):

如果使用该UV_RUN_NOWAIT模式运行循环,则超时为0。

如果要停止循环(uv_stop()被调用),则超时为0。

如果没有活动的句柄或请求,则超时为0。

如果有任何空闲的句柄处于活动状态,则超时为0。

如果有任何要关闭的句柄,则超时为0。

如果以上情况均不匹配,则采用最接近的定时器超时,或者如果没有活动的定时器,则为无穷大。


7.检查句柄回调,此时如果有可读可写的

操作就调用相应回调,如果超时了就调用超时回调。

8.如果通过调用uv_close()函数关闭,则调用close关闭。

9.在超时后更新下一次循环时间。通过UV_RUN_DEFAULT模式运行循环。


uv_run(loop, UV_RUN_DEFAULT);


读取写入是一个会降低性能的过程,与cpu速度差的很多,所以要改善这个问题。

1744f5680dc6423d814dddc110092463.png

常见的解决方式是多线程,但是libuv采用了异步的解决方法,非阻塞风格。

初始化loop前,给其分配相应的内存。在用uv_loop_close(uv_loop_t *)关闭loop后,要回收内存空间。

libuv通过创造对应的I/O设备、定时器、进程等handle来实现。

handle是不透明的数据结构,其中对应的类型uv_TYPE_t的type指定handle的使用目的。


handle(句柄)代表持久性对象。相应的handle有许多相关联的request,request是一个短暂性对象(对比于持久性就是只维持一个回调函数的时间),对映着handle的I/O操作。



目录
打赏
0
0
0
0
172
分享
相关文章
Windows Server 2019 DHCP服务器搭建
Windows Server 2019 DHCP服务器搭建
208 3
springboot如何配置influxdb
【6月更文挑战第24天】springboot如何配置influxdb
537 0
Android应用开发:实现自定义ViewPager2的完全指南
【5月更文挑战第23天】 在移动应用开发的领域中,为用户提供流畅且直观的界面体验至关重要。Android平台上的ViewPager2组件提供了一个强大的方式来实现可滑动的页面,但有时候默认的行为和样式可能无法满足特定的设计要求。本文将深入探讨如何通过创建一个自定义的ViewPager2来扩展其功能,包括实现新的转换效果、修改指示器样式以及增加触摸事件响应等。我们将提供详尽的步骤和代码示例,帮助开发者掌握创建高度定制的ViewPager2所需的关键概念和技术。
MySQL查询执行计划详解(EXPLAIN)
一、单表查询 访问方法/访问类型: • const:通过主键值或唯一二级索引与一个常熟进行等值查询(不包括NULL),只会生成一条记录 • ref:普通二级索引与一个常数进行等值比较,可能生成多条记录 • ref_or_null:ref的前提下可以加上or key is null • range:对应的扫描区间为若干个单点扫描区间或范围扫描区间(不包括负无穷到正无穷的范围) • index:扫描区间为全表,但是可以在二级索引中扫描(因为二级索引每条记录占用空间更小,所以需要读的页更少) • all:直接扫描全部的聚集索引记录
Windows下部署SpringBoot的实践方案(Docker & Docker Desktop)
Windows下部署SpringBoot的实践方案(Docker & Docker Desktop)
597 0
【Android App】低功耗蓝牙中扫描BLE设备的讲解及实战(附源码和演示 超详细)
【Android App】低功耗蓝牙中扫描BLE设备的讲解及实战(附源码和演示 超详细)
975 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问