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原理分析的更多相关文章

  1. Android应用程序组件Content Provider在应用程序之间共享数据的原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6967204 在Android系统中,不同的应用 ...

  2. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析

    1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...

  3. Spring Cloud之负载均衡组件Ribbon原理分析

    目录 前言 一个问题引发的思考 Ribbon的简单使用 Ribbon 原理分析 @LoadBalanced 注解 @Qualifier注解 LoadBalancerAutoConfiguration ...

  4. openwrt procd启动流程和脚本分析

    Linux内核执行start_kernel函数时会调用kernel_init来启动init进程,流程如下图: graph LR A[start_kernel] -->B(rest_init) B ...

  5. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  6. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  7. SPI协议及工作原理分析

    说明.文章摘自:SPI协议及其工作原理分析 http://blog.csdn.net/skyflying2012/article/details/11710801 一.概述. SPI, Serial ...

  8. Android ListView实现不同item的方法和原理分析

    ListView实现不同item的方法和原理分析 一问题抛出Listview是android里面的重要组件,用来显示一个竖向列表,这个没有什么问题:但是有个时候列表里面的item不是一样的,如下图,列 ...

  9. 转载:solr MoreLikeThis的原理分析

    转载地址:http://blog.sina.com.cn/s/blog_5ddc071f0101muos.html 在solr中有两种方式实现MoreLikeThis:MoreLikeThisHand ...

随机推荐

  1. QT网络编程Tcp下C/S架构的即时通信

    先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面. #ifndef TCPCLIENT_H #define TCPCLIENT_H #include <QDialog> #in ...

  2. python接口自动化4-绕过验证码登录(cookie) (转载)

    前言 有些登录的接口会有验证码:短信验证码,图形验证码等,这种登录的话验证码参数可以从后台获取的(或者查数据库最直接). 获取不到也没关系,可以通过添加cookie的方式绕过验证码. 一.抓登录coo ...

  3. kali配置ip,更新源,更新签名

    以下是我在简单玩kali时候碰到的一些问题,然后找到的解决办法,能成功解决我当时碰到的问题,如果你有疑问或者碰到不能解决的问题可以在下面评论 ############################# ...

  4. sql语句的group by 与 inner join

    一.理解group by和聚合函数 先来看下表1,表名为test: 表1 执行如下SQL语句: 1 2 SELECT name FROM test GROUP BY name 你应该很容易知道运行的结 ...

  5. IBM MQ介绍

    转自:http://hi.baidu.com/lubezhang/blog/item/bd308b3b7ecce3ec14cecb4f.html IBM MQ(IBM Message Queue)是I ...

  6. Swift3.0 调用C函数-_silen_name

    一般情况下Swit要想调用obj-c,c或c++代码必须通过obj-c以及桥接文件才可以办到,但是使用@_silgen_name,可以对于某些简单的代码,直接跳过桥接文件和.h头文件与C代码交互. 创 ...

  7. 优秀的WEB前端开发框架:Bootstrap!

    其实早就对Bootstrap有所耳闻,大概了解这哥们是做WEB前端的 但直到昨天以前,还没有对他产生任何深入了解的兴趣 冷落他的主要原因还是觉得会束缚手脚,毕竟自己多年来在WEB前端的积累一直没有停滞 ...

  8. zip 函数

    zip 函数,看上去是打包的意思,其实功能是将多个可迭代对象,组合成一个个元组. zip(iter1,iter2) a,b = zip(*zip(iter1,iter2)) a = [1,2,3] b ...

  9. 3springboot:springboot配置文件(配置文件、YAML、属性文件值注入<@Value、@ConfigurationProperties、@PropertySource,@ImportResource、@Bean>)

    1.配置文件: springboot默认使用一个全局配置文件 配置文件名是固定的   配置文件有两种(开头均是application,主要是文件的后缀): ->application.prope ...

  10. css3中的变形 transform详解

    一.变形-旋转 ratate()函数 通过指定的角度参数使元素相对原点进行旋转.它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度.如果这个值为正值,元素相对原点中心顺时针旋转:如果这 个 ...