EmxUV

对于libuv的封装,提供了线程池,定时器,异步操作等接口 更多...

EmxUV 的协作图:

class  Emx::EuvAsync
 实现基于Loop的异步事件通知 更多...
 
class  Emx::EuvDns
 用于异步解析DNS 更多...
 
class  Emx::EuvIdle
 空闲回调,当loop处于空闲状态时会触发此事件 更多...
 
class  Emx::EuvLoop
 实现多路复用循环的主体,所有基于EuvLoop的事件都应绑定到一个EuvLoop上 更多...
 
class  Emx::EuvPipe
 以pipe为底层通信基础实现接口类EuvStreamInf,pipe的底层使用STREAM+AF_UNIX的方式进行通信。 更多...
 
class  Emx::EuvPipeClientBase
 使用EuvPipe作为EuvStreamInf,并且继承EuvStmClientBase, 形成以Pipe为底层通信机制面向连接的客户端 更多...
 
class  Emx::EuvPipeServerClient
 使用EuvPipe作为EuvStreamInf,并且继承EuvStmServerClientBase, 形成以Pipe为底层通信机制面向连接的ServerClient端 更多...
 
class  Emx::EuvPipeServerHost
 使用EuvTcp作为EuvStreamInf,并且继承EuvStmServerHostBase, 形成以TCP为底层通信机制面向连接的ServerHost端 更多...
 
class  Emx::EuvPoll
 EuvPoll可以实现所有文件描述符的监听,可以实现读写和连接状态的监听, 当某些描述符并不是文件或者socket或者描述符已经被打开的时候可以考虑使用这个, 例如海思中获取venc的时候使用的HI_S32 HI_MPI_VENC_GetFd(VENC_CHN VeChn)函数获取的fd 更多...
 
class  Emx::EuvSignal
 实现基于Loop的异步事件通知 更多...
 
class  Emx::EuvStmClientBase
 面向连接的socket通信Client端基类,实现了这种类型客户端的创建销毁发送接收, 内部使用EuvStreamInf抽象接口作为底层通信接口,实际实现客户端的时候,需要传入继承EuvStreamInf的实例 并且最终的客户端需要继承EuvStmClientBase类,实现其各种虚函数。可参MsgRpcRep的实现 更多...
 
class  Emx::EuvStmServerHostBase
 面向连接的socket通信ServerHost端基类,是服务端的监听socket,实现了这种类型ServerHost端的创建销毁发送接收, 内部使用EuvStreamInf抽象接口作为底层通信接口,实际实现服务端的时候,需要传入继承EuvStreamInf的实例 并且最终的服务端需要继承EuvStmCServerHostBase类,实现其各种虚函数。可参MsgRpcServer的实现 更多...
 
class  Emx::EuvStmServerClientBase
 面向连接的socket通信ServerClient端基类,是服务端accept后的socket, 实现了这种类型ServerClient端的创建销毁发送接收, 内部使用EuvStreamInf抽象接口作为底层通信接口,实际实现服务端的时候,需要传入继承EuvStreamInf的实例 并且最终的服务端需要继承EuvStmCServerClientBase类,实现其各种虚函数。可参MsgRpcClient的实现 更多...
 
class  Emx::EuvStreamInf
 面向链接类型的抽象接口(例如tcp/pipe),用于为EuvStmClientBase/EuvStmServerHostBase等提供统一的底层通信接口 更多...
 
class  Emx::EuvTcp
 以tcp为底层通信基础实现接口类EuvStreamInf。 更多...
 
class  Emx::EuvTcpClientBase
 使用EuvTcp作为EuvStreamInf,并且继承EuvStmClientBase, 形成以TCP为底层通信机制面向连接的客户端 更多...
 
class  Emx::EuvTcpServerClient
 使用EuvTcp作为EuvStreamInf,并且继承EuvStmServerClientBase, 形成以TCP为底层通信机制面向连接的ServerClient端 更多...
 
class  Emx::EuvTcpServerHost
 使用EuvTcp作为EuvStreamInf,并且继承EuvStmServerHostBase, 形成以TCP为底层通信机制面向连接的ServerHost端 更多...
 
class  Emx::EuvTimer
 基于EuvLoop的定时器,很有用的一个东西 更多...
 
class  Emx::EuvUdp
 基于EuvLoop的UDP异步接收发送类 更多...
 
class  Emx::EuvWork
 提供在EuvLoop内调用线程池执行阻塞耗时任务的机制 更多...
 

详细描述

Euv部分是针对Emx开发人员需要使用的部分,SDK的使用者需要了解本小结中关于EuvLoop的使用

Emx的日常编程中会经常使用到Euv提供的各种组件,需要开发人员熟练掌握Euv的使用方法和内部原理

  Euv模块是对开源libuv库的C++封装,其拥有跨平台的特性,内部使用select/epoll/kqueue/IOCP等技术来完成IO的多路复用,Emx的整体架构都是基于此特性构建出来,关于libuv的详细介绍可参考libuv

  Euv的核心是EuvLoop,一个EuvLoop就是一个线程,是各路IO复用的载体,负责如EuvAsync/EuvDns/EuvTimer/EuvTcp等句柄(事件)的监听和运行,EuvLoop启动运行后,对参与EuvLoop循环的所有句柄的操作都必须在EuvLoop内进行(EuvAsync除外),否则将面临线程安全的问题。在EuvLoop启动之前可以注册若干个事件,启动后也可在loop内执行注册事件操作(不可在loop外执行),EuvLoop内部使用select/epoll等去监听这些注册的事件,举个EuvTimer定时器的例子

#include "EmxCore.hpp"
// Emx2.0统一使用Emx作为顶级命名空间
using namespace Emx;
//一个定时器的例子
class Timer {
public:
//启动例子
void Start() {
//初始化一个EuvLoop,并将EuvLoop命名为"TimerExample",
//这个名字可以通过pstree命令看到
//使用lambda表达式来定义当此EuvLoop结束时需要做的操作
//注意:想要EuvLoop顺利退出,必须在这里关闭此EuvLoop下监听的所有句柄才行
m_loop.Init("TimerExample", [this]() {
//StopAndDeInit执行后会在某次循环中运行这里
//销毁timer
m_timer.Destroy();
});
//创建并初始化一个timer,绑定到m_loop上运行
m_timer.Create(m_loop);
//启动(注册)timer,将启动时间定为1000ms,表示循环启动后的1s会触发超时回调
//将重复间隔定位2000ms,表示第一次超时后每隔2s将再次超时
//使用lambda表达式定义一个timer定时器超时触发的回调,也可使用下面的bind方式
//m_timer.Start(1000, 2000, std::bind(&Timer::OnTimer,this));
m_timer.Start(1000, 2000, [this] { OnTimer(); });
//启动EuvLoop线程,循环开始
m_loop.Start();
}
//结束例子
void Stop() {
//结束并关闭一个EuvLoop,此时会导致EuvLoop Init时注册的OnQuit回调被调用
//然后等待EuvLoop监听的所有句柄都被关闭了,EuvLoop就顺利退出了,否则会一直阻塞在这里
//此函数可以在EuvLoop之外的线程调用,例如此例子中就是在main线程调用的此函数,而不是EuvLoop线程
m_loop.StopAndDeInit();
}
private:
void OnTimer() {
//此打印将在EuvLoop启动后1s时打印一次,然后每隔2s打印一次
printf("%s:%d reached timeout\n", __FUNCTION__, __LINE__);
//注意类似OnTimer这种注册的回调函数都是运行在EuvLoop线程中的
//在这些回调函数内部可以使用如m_timer.Create/m_timer.Start/m_timer.Stop/pipe.Create等操作句柄的参数。
//当EuvLoop运行起来后,在EuvLoop外,也就是其他线程中是不允许操作这些函数的,唯一的例外是async.Send()函数
}
private:
EuvLoop m_loop;//定义一个EuvLoop循环
EuvTimer m_timer;//定义一个定时器
};
int main(int argc, char *argv[]) {
Timer timer;//定义Timer对象
timer.Start();//启动Timer
sleep(8);//等一等
timer.Stop();//结束Timer
return 0;
}
Definition: EmxGpio.hpp:10

  必须注意的是,因为一个EuvLoop就是一个线程,所以所有注册在这个loop中的事件回调都是按照事件的发生顺序依次执行的,虽然这使得loop内的各个事件之间共享资源变得更加安全,但同时也意味着任意事件回调处理的阻塞都将阻塞后面的所有事件,所以需要留意回调函数内部代码的阻塞问题。Emx中出现的所有需要绑定EuvLoop的回调函数都需要注意这个问题,例如异步实时流获取,SD卡状态回调等等。