`
CshBBrain
  • 浏览: 643049 次
  • 性别: Icon_minigender_1
  • 来自: 成都
博客专栏
B7d9bf34-126e-301f-819e-81f2615b5a2a
开源WebSocket服务...
浏览量:143150
Group-logo
HTML5移动开发
浏览量:136507
社区版块
存档分类
最新评论

Proactor和Reactor模式_继续并发系统设计的扫盲

阅读更多

转自:http://www.cppblog.com/kevinlynx/archive/2008/06/06/52356.html

 

 

Proactor和Reactor都是并发编程中的设计模式。在我看来,他们都是用于派发/分离IO操作事件的。这里所谓的
IO事件也就是诸如read/write的IO操作。"派发/分离"就是将单独的IO事件通知到上层模块。两个模式不同的地方
在于,Proactor用于异步IO,而Reactor用于同步IO。

摘抄一些关键的东西:

"
Two patterns that involve event demultiplexors are called Reactor and Proactor [1]. The Reactor patterns 
involve synchronous I/O, whereas the Proactor pattern involves asynchronous I/O.
"

关于两个模式的大致模型,从以下文字基本可以明白:

"
An example will help you understand the difference between Reactor and Proactor. We will focus on the read 
operation here, as the write implementation is similar. Here's a read in Reactor:

* An event handler declares interest in I/O events that indicate readiness for read on a particular socket ;
* The event demultiplexor waits for events ;
* An event comes in and wakes-up the demultiplexor, and the demultiplexor calls the appropriate handler; 
* The event handler performs the actual read operation, handles the data read, declares renewed interest in 
  I/O events, and returns control to the dispatcher .

By comparison, here is a read operation in Proactor (true async):

* A handler initiates an asynchronous read operation (note: the OS must support asynchronous I/O). In this 
  case, the handler does not care about I/O readiness events, but is instead registers interest in receiving 
  completion events;
* The event demultiplexor waits until the operation is completed ;
* While the event demultiplexor waits, the OS executes the read operation in a parallel kernel thread, puts 
  data into a user-defined buffer, and notifies the event demultiplexor that the read is complete ;
* The event demultiplexor calls the appropriate handler; 
* The event handler handles the data from user defined buffer, starts a new asynchronous operation, and returns
  control to the event demultiplexor.

"

可以看出,两个模式的相同点,都是对某个IO事件的事件通知(即告诉某个模块,这个IO操作可以进行或已经完成)。在结构
上,两者也有相同点:demultiplexor负责提交IO操作(异步)、查询设备是否可操作(同步),然后当条件满足时,就回调handler。
不同点在于,异步情况下(Proactor),当回调handler时,表示IO操作已经完成;同步情况下(Reactor),回调handler时,表示
IO设备可以进行某个操作(can read or can write),handler这个时候开始提交操作。

用select模型写个简单的reactor,大致为:

 

///
class handler
{
public:
    virtual void onRead() = 0;
    virtual void onWrite() = 0;
    virtual void onAccept() = 0;
}


class dispatch
{
public:
    void poll()
    {
        // add fd in the set.
        
//
        
// poll every fd
        int c = select( 0, &read_fd, &write_fd, 0, 0 );
        if( c > 0 )
        {
            for each fd in the read_fd_set
            {    if fd can read
                    _handler->onRead();
                if fd can accept
                    _handler->onAccept();
            }
 

            for each fd in the write_fd_set
            {
                if fd can write
                    _handler->onWrite();
            }

        }

    }
 

    void setHandler( handler *_h )
    {
        _handler = _h;
    }
 

private:
    handler *_handler;
}


/// application
class MyHandler : public handler
{
public:
    void onRead()
    {
    }
 

    void onWrite()
    {
    }
 

    void onAccept()
    {
    }

}



在网上找了份Proactor模式比较正式的文档,其给出了一个总体的UML类图,比较全面:

proactor_uml

根据这份图我随便写了个例子代码:

 

class AsyIOProcessor
{
public:
    void do_read()
    {
        //send read operation to OS
        
// read io finished.and dispatch notification
        _proactor->dispatch_read();
    }
 

private:
    Proactor *_proactor;
}


class Proactor
{
public:
    void dispatch_read()
    {
        _handlerMgr->onRead();
    }
 

private:
    HandlerManager *_handlerMgr;
}


class HandlerManager
{
public:
    typedef std::list<Handler*> HandlerList; 

public:
    void onRead()
    {
        // notify all the handlers.
        std::for_each( _handlers.begin(), _handlers.end(), onRead );
    }
 

private:
    HandlerList *_handlers;
}


class Handler
{
public:
    virtual void onRead() = 0;
}


// application level handler.
class MyHandler : public Handler
{
public:
    void onRead() 
    {
        // 
    }

}



Reactor通过某种变形,可以将其改装为Proactor,在某些不支持异步IO的系统上,也可以隐藏底层的实现,利于编写跨平台
代码。我们只需要在dispatch(也就是demultiplexor)中封装同步IO操作的代码,在上层,用户提交自己的缓冲区到这一层,
这一层检查到设备可操作时,不像原来立即回调handler,而是开始IO操作,然后将操作结果放到用户缓冲区(读),然后再
回调handler。这样,对于上层handler而言,就像是proactor一样。详细技法参见这篇文章

其实就设计模式而言,我个人觉得某个模式其实是没有完全固定的结构的。不能说某个模式里就肯定会有某个类,类之间的
关系就肯定是这样。在实际写程序过程中也很少去特别地实现某个模式,只能说模式会给你更多更好的架构方案。

最近在看spserver的代码,看到别人提各种并发系统中的模式,有点眼红,于是才来扫扫盲。知道什么是leader follower模式
reactor, proactor,multiplexing,对于心中的那个网络库也越来越清晰。

最近还干了些离谱的事,写了传说中的字节流编码,用模板的方式实现,不但保持了扩展性,还少写很多代码;处于效率考虑,
写了个static array容器(其实就是template <typename _Tp, std::size_t size> class static_array { _Tp _con[size]),
加了iterator,遵循STL标准,可以结合进STL的各个generic algorithm用,自我感觉不错。基础模块搭建完毕,解析了公司
服务器网络模块的消息,我是不是真的打算用自己的网络模块重写我的验证服务器?在另一个给公司写的工具里,因为实在厌恶
越来越多的重复代码,索性写了几个宏,还真的做到了代码的自动生成:D。

对优雅代码的追求真的成了种癖好.  = =|

分享到:
评论

相关推荐

    Proactor和Reactor模式_继续并发系统设计的扫盲[参照].pdf

    在并发系统设计中,Proactor和Reactor模式是两种常用的设计模式,它们主要用来处理I/O操作的事件派发和分离。这两种模式都是为了提高系统的并发能力,优化资源利用,但它们在处理I/O事件的方式上有所不同。 首先,...

    Proactor模式&Reactor模式详解

    ACE proactor 与 Reactor 模式的详解

    tpd_reactor_proactor.pdf

    Reactor 和 Proactor 模式是两种常见的事件处理模式,在网络编程中广泛应用于设计高效、可靠的并发和网络应用程序。在本文中,我们将详细介绍 Reactor 和 Proactor 模式的概念、特点、优缺点,以及在网络编程中的...

    p401 - p418 proactor -Reactor模型

    下面我们来详细了解 Proactor-Reactor 模式的设计思想和实现机理。 问题背景 在设计高性能服务器时,如何处理大量客户端连接是关键问题之一。最直接的方法是为每个连接创建一个线程,但是这种方法会带来性能开销和...

    actor和proactor模式1

    在IT领域,特别是网络编程和并发处理中,`Actor`和`Proactor`模式是两种重要的设计模式,它们主要用于高效地处理I/O操作。这两种模式都涉及到如何有效地管理多个并发的I/O请求,以提高系统性能和响应速度。 首先,...

    ACE Reactor 和proactor 通信方式两套代码

    本人学习ACE 时候写的关于两种通信方式的实例代码,我把三个连写都写在了一个文件,根据需要注释掉其他的就行。 ACE用于开发通信程序非常方便,尤其相对于WinSock 来说,可以省很多代码,普通程序员也更容易理解

    cpp-利用C编写的HTTP服务器使用线程池Reactor模式

    通过阅读源代码和文档,你可以了解线程池和Reactor模式在实际项目中的具体应用,这对于提升你的网络编程技能非常有帮助。如果你计划进一步扩展这个服务器,可以考虑增加对HTTPS的支持,优化线程池的调度策略,或者...

    Nerv.zip_linux 服务器_socket 高并发_socket高并发_跨平台_跨平台socket

    - 事件驱动/异步I/O:例如使用Reactor或Proactor模式,如libevent和libev库,实现非阻塞I/O。 7. **性能优化**:为了提升服务器性能,还需要关注以下方面: - 连接池:复用已建立的连接,减少建立和释放连接的...

    ACE_Proactor网络通信示例代码

    ACE_Proactor是ACE库中的一个核心组件,它提供了一种异步事件处理机制,使得开发者可以编写非阻塞的、高性能的网络应用。...同时,这也能帮助你理解如何在多线程环境中有效地利用系统资源,提高网络应用的并发性能。

    对ACE的Proactor通讯模式的全面封装

    Proactor模式是ACE库中提供的一种异步事件处理模型,它允许程序在非阻塞方式下处理I/O操作,提高了系统的并发处理能力。本封装主要目的是使开发者能够在不直接接触ACE底层细节的情况下,利用Proactor模式实现高效的...

    ACE_Proactor TCP协议通信示例代码

    2. **ACE_Proactor模式**:ACE_Proactor是基于事件的非阻塞I/O模型,它使用了异步事件驱动的编程模型。在该模型中,I/O操作是启动后立即返回的,然后由Proactor在后台处理,当操作完成时,Proactor通过回调函数通知...

    ACE网络编程模式比较

    **ACE网络编程模式详解** ACE(Adaptive Communication ...Reactor和Proactor模式适合单线程环境,半同步/半异步和领导者/跟随者模式则适用于多线程环境。理解这些模式的优缺点,有助于设计出更高效、健壮的网络应用。

    两种高性能IO设计模式(ReactorProactor)的比较.docx

    本文主要对比了两种主要的I/O多路复用模式:Reactor和Proactor,这两种模式都是为了克服传统阻塞I/O的性能瓶颈而提出的。 首先,阻塞I/O在调用操作时会占用调用线程,直到操作完成,导致资源浪费和低效率。而非阻塞...

    Network Pattern

    常见的网络模式有Reactor和Proactor两种,它们在并发处理和异步操作中扮演着关键角色。 **Reactor模式** Reactor模式是一种事件驱动的设计模式,广泛应用于多线程和网络编程。它的核心思想是通过一个中心调度器...

    ACE并发编程示例及Task类的实现

    1. **多路复用器(Multiplexer)**:ACE_Task可以与ACE_Reactor或ACE_Proactor进行集成,实现事件驱动的并发处理。Reactor模式适用于处理同步I/O,而Proactor模式则适用于异步I/O。 2. **输入/输出端口(Input/...

    Windows下采用IOCP实现的ACE的Proactor框架剖析

    它允许应用程序处理大量的并发I/O操作,特别适合于网络服务器和其他需要大量并发读写操作的应用。IOCP通过将I/O操作与处理结果的回调函数解耦,从而避免了传统的轮询或阻塞I/O可能导致的性能瓶颈。 **IOCP工作原理*...

    两种高性能IO设计模式(ReactorProactor)的比较

    两种高性能IO设计模式(Reactor和Proactor)比较 在高性能服务器设计中,I/O设计模式扮演着至关重要的角色。常见的I/O设计模式有阻塞型、非阻塞同步型和非阻塞异步型。其中,非阻塞异步型I/O设计模式是性能最高、...

    ACE服务器 全面开源

    很全面的ACE服务器,包括proactor、reactor模式

    非阻塞IO+Proactor+日志系统 自定义协议服务器.zip

    在C++中,可以使用套接字API(如`select`、`poll`或`epoll`)来实现非阻塞I/O,也可以利用Boost.Asio库,它为异步I/O和Proactor模式提供了高级接口。同时,C++标准库中的`std::future`和`std::async`可以用于实现...

    ACE Reactor相关的知识

    ACE Reactor 模式的核心是一个事件调度器,它监控操作系统提供的事件多路分离接口,检测到事件发生后,通过回调机制通知预先注册的事件处理器(event handler)进行处理。事件处理器是用户自定义的类,继承自 ACE_...

Global site tag (gtag.js) - Google Analytics