openWrt libubox组件之uloop原理分析
1. libubox概述
libubox是openwrt新版本中的一个基础库,有很多应用是基于libubox开发的,如uhttpd,netifd,ubusd等。
- libubox主要提供以下两种功能:
提供一套基于事件驱动的机制;
提供多种开发支持接口,如链表、kv链表、平衡查找二叉树、md5、json等。
- 使用libubox开发的好处有如下几点:
可以使程序基于事件驱动,从而可实现在单线程中处理多个任务;
基于libubox提供的API可以加快开发进度,提高程序的稳定性;
能更好的将程序融入openwrt架构中,因为新的openwrt的很多应用和库都基于libubox开发,当前分析使用的libubox版本为libubox-2014-08-04。
2. uloop
uloop是libubox下的一个模块,有三个功能:文件描述符触发事件的监控,timeout定时器处理, 当前进程的子进程的维护。
2.1 整体框架
2.1.1 主框架接口
- 初始化事件循环
int uloop_init(void)
创建一个epoll的句柄,最多监控32个文件描述符。
设置文件描述符属性,如FD_CLOEXEC。
- 事件循环主处理入口
void uloop_run(void)
- 销毁事件循环
void uloop_done(void)
关闭epoll句柄。
清空定时器链表中的所有的定时器。
清空进程处理事件链表中删除所有的进程事件节点。
2.1.2 主框架流程

uloop_run轮询处理定时器、进程、描述符事件。
- 遍历定时器timeouts链表判断是否有定时器超时,如果有则进行相应的回调处理,没有跳过。
- 判断是否有子进程退出SIGCHLD信号,有就会遍历processes进程处理的链表,调勇相应的回调函数,没有跳过。
- 计算出距离下一个最近的定时器的时间,作为文件描述符事件epoll的超时时间。然后epoll进行事件监听,如果有文件描述符准备就绪(可读写时间)则调用相应的回调函数,或者有信号进行中断epoll返回停止监听,否则epoll阻塞直到超时时间完成。
2.2 描述符事件
2.2.1 文件描述符uloop结构
struct uloop_fd
{
uloop_fd_handler cb; /*文件描述符对应的处理函数 */
int fd; /*文件描述符*/
bool eof; /*EOF*/
bool error; /*出错*/
bool registered; /*是否已经添加到epoll的监控队列*/
uint8_t flags; /*ULOOP_READ | ULOOP_WRITE | ULOOP_BLOCKING等*/
};
2.2.2 描述符uloop使用接口
- 注册一个新描述符到事件处理循环
int uloop_fd_add(struct uloop_fd *sock, unsigned int flags)
uloop最多支持10个描述符事件。
- 从事件处理循环中销毁指定描述符
int uloop_fd_delete(struct uloop_fd *sock)
2.2.3 描述符事件流程
2.3 定时器事件
2.3.1 定时器timeout结构
struct uloop_timeout
{
struct list_head list; //链表节点
bool pending; //添加一个新的timeout pending是true, false删除该节点timeout
uloop_timeout_handler cb; //超时处理函数
struct timeval time; //超时时间
};
2.3.2 定时器使用接口
- 注册一个新定时器
int uloop_timeout_add(struct uloop_timeout *timeout)
用户不直接使用,内部接口,被接口uloop_timeout_set调用。
将定时器插入到timeouts链表中,该链表成员根据超时时间从小到大排列。

- 设置定时器超时时间(毫秒),并添加
int uloop_timeout_set(struct uloop_timeout *timeout, int msecs)
如果pending为true,则从定时器链表中删除原先已存在的定时器。
设置定时器的超时时间点。
调用uloop_timeout_add接口将该定时器加入到定时器链表中。
- 销毁指定定时器
int uloop_timeout_cancel(struct uloop_timeout *timeout)
从定时器链表中删除指定定时器。
- 获取定时器还剩多长时间超时
int uloop_timeout_remaining(struct uloop_timeout *timeout)
这里pending标记可判断定时器是否处于生命周期,如果尚处在生命周期内,则返回离定时器超时还有多少时间,单位为毫秒。
2.3.3 定时器的使用
用户使用定时器非常简单
struct uloop_timeout *t; //第一步定义一个定时器并申请内存空间
t = malloc(sizeof(*t));
t->cb = light_ctl_check_cb; //第二步指定回调函数
t->pending = false;
uloop_timeout_set(t, 2000); //第三步设置定时器超时时间
2.3.4 定时器功能流程
遍历定时器链表,如果有定时器已经超时,执行该定时器的回调函数。
2.4 进程事件
2.4.1 进程事件处理结构
struct uloop_process {
struct list_head list;
bool pending;
uloop_process_handler cb; /** 文件描述符, 调用者初始化 */
pid_t pid; /** 文件描述符, 调用者初始化 */
};
2.4.2 进程事件使用接口
- 注册新进程到事件处理循环
int uloop_process_add(struct uloop_process *p)
将进程事件插入到进程事件链表中,链表根据PID从小到大排序。
其中p->proc.pid为注册到uloop监控的进程ID。
P->cb为进程退出的回调函数,类型为:
typedef void (*uloop_process_handler)(struct uloop_process *c, int ret)
- 从事件处理循环中销毁指定进程
int uloop_process_delete(struct uloop_process *p)
从进程事件处理链表中删除该进程事件。
2.4.3 进程事件处理流程
openWrt libubox组件之uloop原理分析的更多相关文章
- Android应用程序组件Content Provider在应用程序之间共享数据的原理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6967204 在Android系统中,不同的应用 ...
- Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析
1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...
- Spring Cloud之负载均衡组件Ribbon原理分析
目录 前言 一个问题引发的思考 Ribbon的简单使用 Ribbon 原理分析 @LoadBalanced 注解 @Qualifier注解 LoadBalancerAutoConfiguration ...
- openwrt procd启动流程和脚本分析
Linux内核执行start_kernel函数时会调用kernel_init来启动init进程,流程如下图: graph LR A[start_kernel] -->B(rest_init) B ...
- 转载:AbstractQueuedSynchronizer的介绍和原理分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- Camel运行原理分析
Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...
- SPI协议及工作原理分析
说明.文章摘自:SPI协议及其工作原理分析 http://blog.csdn.net/skyflying2012/article/details/11710801 一.概述. SPI, Serial ...
- Android ListView实现不同item的方法和原理分析
ListView实现不同item的方法和原理分析 一问题抛出Listview是android里面的重要组件,用来显示一个竖向列表,这个没有什么问题:但是有个时候列表里面的item不是一样的,如下图,列 ...
- 转载:solr MoreLikeThis的原理分析
转载地址:http://blog.sina.com.cn/s/blog_5ddc071f0101muos.html 在solr中有两种方式实现MoreLikeThis:MoreLikeThisHand ...
随机推荐
- Linux->解决用userdel删除不掉用户的问题
情况: 一般我们移除,都是先把用户从组中删除,再依次把组删掉,但是这里出现了问题: root@ per# userdel -r mysql userdel: user mysql is current ...
- DevExpress GridControl如何取消默认的显示方式
DevExpress GridControl如何取消默认的显示方式,就是表格中好像还嵌套了一个表格,下面有个折叠‘+’按钮,我需要显示的是就是单表格的样式效果. 默认的样式如图: 我需要显示的效果图: ...
- 监控DAG状态
Add-PSSnapin microsoft.exchange* Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 $server ...
- redis知识树
- 自开发Web应用和SAP Customer Data Cloud Identity服务的集成
今天的文章继续由SAP成都研究院的云时代女王,Aviva给大家分享关于SAP Customer Data Cloud的一些使用经验. Aviva之前的文章可以在本文末尾处获得. 下面是她的正文. 大家 ...
- PhoneGap 的存储 API_localStorage 和 sessionStorage
一.介绍 1.为了替代Cookile这门古老的客户端存储技术,Html5的WEB Storage Api 提供了俩中在 客户端存储数据库的方法:localStorage 和 sessionStorag ...
- 安装MySql-Python遇到的错误及解决方法
用pip安装mysql-python时报错: _mysql.c _mysql.c(42) : fatal error C1083: Cannot open include file: 'config- ...
- python 3.6.3 异常
内置异常 在Python中,所有异常都必须是派生类的实例 BaseException.在try同一个声明中except 说提到一类特殊条款,该条款还处理来自类(从中但也不例外类派生的任何异常类它派生) ...
- 通过nginx 499 来判断服务端超时数量
这个其实不能算一篇文章,因为内容太少了,就当记点笔记吧. (1)什么是 nginx 499 499 其实是 nginx 下特有的 http 状态码,代表客户端主动断开了连接,导致服务器无法返回 htt ...
- web.xml中Filter的作用
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml文件配置好要 ...

