Reactor_事件模式

Reactor模式解析

Reactor事件驱动模式

一,什么是Reactor模式?

1.它的中文名叫反应器,是事件驱动中的一种(还有另外一种叫Proactor:主动器)

2.在我们写一些比较小的[服务器-客户端]的时候,经常简单地使用BSD Socket(accept,connect,recv,send等等),

但是这样的话,程序的[Socket处理逻辑]和[业务逻辑]就混合在一起,导致2者的耦合性非常高,Reactor模式正是为了

解决这种耦合性而诞生的

3.Reactor(反应器)是相对于调用者而言的,因为调用之后,当有事件,Reactor就会通知我们,我们就去响应事件。

二,Reactor模式的实现(C++):

(1).实现类简介:

1.多路复用组件接口:IReactor

2.具体多路复用组件:CSelectReactor(在Windows是用select实现,在Linux可以用epoll等等)

3.事件组件接口:IEvent(事件是和Socket关联在一起的)

4.具体事件组件:CAcceptEvent,CReadEvent

 

(2).实现思路:

1.定义一个具体的多路复用组件,该组件负责:

A.多路复用事件

B.注册一个事件到多路复用事件列表中

C.当有事件发生,判断事件的类型(分别有:Read,Write),然后调用分别调用事件的Read事件或者Write事件

2.定义事件,事件都是继承于IEvent接口类,并且提供2个接口:

A.ReadEvent接口,当有Read事件的时候,该接口会被调用

B.WriteEvent接口,当有Write事件的时候,该接口被调用

(3).实现:

A.多路复用组件接口(IReactor):

 

/////////////类声明///////////////

typedef map<SOCKET, IEvent*> SOCKET_MAP_DEF;//以Socket为映射的IEvent*列表

typedef map<SOCKET, IEvent*>::iterator SOCKET_MAP_ITER_DEF;

 

class IReactor 

{

public:

    virtual int Init() = 0;//初始化

    virtual int Dispatch() = 0;//多路复用Dispatch

 

    int RegisterEvent(IEvent* pEvent);//注册一个Event

    IReactor();

 

protected:

    SOCKET_MAP_DEF cEventMap;

};

 

/////////////类实现///////////////

IReactor::IReactor()

{

    WORD wVersionRequested;

    WSADATA wsaData;

    int err;

 

    wVersionRequested = MAKEWORD( 2, 2 );

 

    err = WSAStartup( wVersionRequested, &wsaData );

    if ( err != 0 ) {

        return;

    }

 

    if ( LOBYTE( wsaData.wVersion ) != 2 ||

        HIBYTE( wsaData.wVersion ) != 2 ) {

            WSACleanup( );

            return; 

    }

}

 

int IReactor::RegisterEvent(IEvent* pEvent)

{

        cEventMap.insert(make_pair(pEvent->GetSocket(), pEvent));//注册事件

        return TRUE;

}

 

B.具体多路复用组件(CSelectReactor):

 

/////////////类声明///////////////

class CSelectReactor : public IReactor//继承于IReactor

{

public:

    int Init();

    int Dispatch();

 

private:

    typedef struct

    {

        FD_SET stReadFDSet;

        FD_SET stWriteFDSet;

        FD_SET stExpFDSet;

    }SELECT_REACTOR_DATA;//select的3中FD,分别用于select函数

 

protected:

    SELECT_REACTOR_DATA stFDSet;

};

 

/////////////类实现///////////////

int CSelectReactor::Init()

{

    return 0;

}

 

int CSelectReactor::Dispatch()

{

    while(1)

    { 

        FD_ZERO(&stFDSet.stReadFDSet);

        FD_ZERO(&stFDSet.stWriteFDSet);

        FD_ZERO(&stFDSet.stExpFDSet);

 

        if (cEventMap.size() == 0)

        {

            break;

        }

 

        //1.根据Event_Type把事件增加到相应的FD中

        for (SOCKET_MAP_ITER_DEF i = cEventMap.begin(); i != cEventMap.end(); i++)

        {

            switch (i->second->GetEventType())

            {

            case enumEvent_Type_Read:

                {

                    FD_SET(i->second->GetSocket(), &stFDSet.stReadFDSet);

                }break;

 

            case enumEvent_Type_Write:

                {

                    FD_SET(i->second->GetSocket(), &stFDSet.stWriteFDSet);

                }break;

            }

        }

 

        //2.开始Select

        int nRet = select(0, &stFDSet.stReadFDSet, &stFDSet.stWriteFDSet, &stFDSet.stExpFDSet, NULL);

        if (nRet == SOCKET_ERROR)//出错

        {

            break;

        }

        else if (nRet == 0)//超时

        {

        }

        else

        {

            for (SOCKET_MAP_ITER_DEF i = cEventMap.begin(); i != cEventMap.end();)

            {

                BOOL bIsEvent = FALSE;

 

                if (FD_ISSET(i->second->GetSocket(), &stFDSet.stReadFDSet))//有Read事件

                {

                    i->second->ReadEvent();

                    bIsEvent = TRUE;

                }

 

                if (FD_ISSET(i->second->GetSocket(), &stFDSet.stWriteFDSet))//有Write事件

                {

                    i->second->WriteEvent();

                    bIsEvent = TRUE;

                }

 

                if(bIsEvent && i->second->IsEventPersist() == FALSE)

                {

                    delete i->second;//!!!这里暂时这样做

                    i = cEventMap.erase(i);

                }

                else

                {

                    i++;

                }

            }

        }

    }

    return 0;

}

 

C.事件组件接口(IEvent):

 

/////////////类声明///////////////

class IEvent

{

public:

    IEvent() { bIsPersist = FALSE; }

    VOID SetEvent(SOCKET hSocket, EVENT_TYPE enumEventType);//设置一个Event的事件

    SOCKET GetSocket();

    EVENT_TYPE GetEventType();

    

    VOID SetEventPersist(BOOL bIsPersist) { this->bIsPersist = bIsPersist; }//设置Event是否[持久性]

    BOOL IsEventPersist() { return bIsPersist == TRUE; }

 

    virtual int ReadEvent() = 0;//Read事件接口

    virtual int WriteEvent() = 0;//Write事件接口

 

protected:

    SOCKET hSocket;

    EVENT_TYPE enumEventType;

    BOOL bIsPersist;

};

 

/////////////类实现///////////////

VOID IEvent::SetEvent(SOCKET hSocket, EVENT_TYPE enumEventType)

{

    this->hSocket = hSocket;

    this->enumEventType = enumEventType;

}

 

SOCKET IEvent::GetSocket()

{

    return hSocket;

}

 

EVENT_TYPE IEvent::GetEventType()

{

    return enumEventType;

}

 

D.具体事件组件(CAcceptEvent,CReadEvent):

class CReadEvent : public IEvent

{

public:

    int ReadEvent()//Read事件

    {

        char szBuf[1024 * 2] = {0};

        int nRet = recv(GetSocket(), szBuf, 1024 * 2, 0);//从Socket读取数据

        if (nRet == -1)//对方关闭Socket

        {

            SetEventPersist(FALSE);

            closesocket(GetSocket());

            return 0;

        }

 

        cout<<"ReadBuffer:"<<szBuf<<endl;

 

        return 0;

    }

 

    int WriteEvent()

    {

        return 0;

    }

};

 

class CAcceptEvent : public IEvent

{

public:

    int ReadEvent()

    {

        CReadEvent* pReadEvent = new CReadEvent(); //客户端的Event

        SOCKADDR_IN stClientAddr = {0};

        int nLen = sizeof(SOCKADDR_IN);

 

        SOCKET hClient = accept(GetSocket(), (SOCKADDR*)&stClientAddr, &nLen);//Accept客户端

        pReadEvent->SetEvent(hClient, enumEvent_Type_Read);

        pReadEvent->SetEventPersist(TRUE);

        pSelectReactor->RegisterEvent(pReadEvent);  //注册到Reactor中

        return 0;

    }

 

    int WriteEvent()

    {

        cout<<"WriteEvent"<<endl;

        return 0;

    }

 

    CAcceptEvent(CSelectReactor* pSelectReactor)

    {

        this->pSelectReactor = pSelectReactor;   

    }

 

protected:

    CSelectReactor* pSelectReactor;

};

 

E.Main函数:

int main()

{

    CSelectReactor cSelect;

    CAcceptEvent* pEvent = new CAcceptEvent(&cSelect);

    SOCKADDR_IN stSockAddr = {0};

 

    stSockAddr.sin_addr.s_addr = INADDR_ANY;

    stSockAddr.sin_family = AF_INET;

    stSockAddr.sin_port = htons(9999);

    SOCKET hSocket = socket(AF_INET, SOCK_STREAM, 0);

    bind(hSocket, (SOCKADDR*)&stSockAddr, sizeof(SOCKADDR));

    listen(hSocket, 5);

 

    pEvent->SetEvent(hSocket, enumEvent_Type_Read);//增加一个Listen的Event

    pEvent->SetEventPersist(TRUE);

 

    cSelect.RegisterEvent(pEvent);//注册到Reacotr中

    cSelect.Dispatch();//Select多路复用

    return 0;

}

<think>我们正在处理关于ACE_Reactor的问题,特别是instance()方法、run_reactor_event_loop()和handle_events()函数的使用和解释。根据用户需求,我们需要解释这些内容,并且回答要结构清晰,使用中文,并生成相关问题。注意:用户要求使用中文回答,并且按照系统级指令处理数学公式(但这个问题可能不涉及数学公式,所以主要关注代码和解释)。由于问题涉及ACE(AdaptiveCommunicationEnvironment)框架中的Reactor模式实现,我们将依次解释:1.ACE_Reactor::instance()方法2.ACE_Reactor::run_reactor_event_loop()方法3.ACE_Reactor::handle_events()方法同时,我们将生成相关问题。步骤:1.解释每个方法的功能和用法。2.提供简单的代码示例(如果适用)。3.生成相关问题。注意:ACE是一个庞大的框架,我们将提供核心解释,并尽量保证准确。</think>### ACE_Reactor核心方法详解 #### 1. `instance()` 方法 这是ACE_Reactor的单例访问器,采用单例模式确保整个进程只有一个Reactor实例: ```cpp ACE_Reactor* reactor = ACE_Reactor::instance(); ``` - **功能**:获取全局唯一的Reactor实例[^1] - **使用场景**:需要跨模块访问Reactor时 - **内存管理**:默认由ACE自动管理生命周期,可通过`ACE_Reactor::instance(new CustomReactor)`自定义实现 #### 2. `run_reactor_event_loop()` 方法 事件循环的核心执行方法: ```cpp reactor->run_reactor_event_loop(); ``` - **工作流程**: 1. 通过`select`/`epoll`等系统调用监听I/O事件 2. 当事件触发时,调用注册的`handle_input`/`handle_output`等处理器 3. 定时执行注册的定时器任务 4. 循环执行直到调用`end_reactor_event_loop()` - **阻塞特性**:默认阻塞式运行,可通过`reactor->owner(ACE_OS::thr_self())`设置非阻塞模式 #### 3. `handle_events()` 方法 单次事件处理接口: ```cpp ACE_Time_Value timeout(0, 100000); // 100ms超时 reactor->handle_events(timeout); ``` - **功能特点**: - 执行**单次**事件检测和处理 - 可指定超时时间(如`ACE_Time_Value::zero`表示非阻塞) - 返回处理的事件数量或-1表示错误 - **典型应用**: ```cpp while (!shutdown_requested) { reactor->handle_events(); // 在主循环中手动驱动 } ``` ### 关键交互关系 ```mermaid graph TD A[instance] --> B[获取Reactor实例] B --> C[注册事件处理器] C --> D[run_reactor_event_loop] C --> E[handle_events] D --> F[持续事件循环] E --> G[单次事件处理] ``` ### 使用示例 ```cpp #include <ace/Reactor.h> #include <ace/Event_Handler.h> class MyHandler : public ACE_Event_Handler { public: int handle_input(ACE_HANDLE fd) override { // 处理数据读取 return 0; } }; int main() { MyHandler handler; ACE_Reactor::instance()->register_handler(&handler, ACE_Event_Handler::READ_MASK); // 启动事件循环 ACE_Reactor::instance()->run_reactor_event_loop(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值