您的位置:首页 > Web前端 > React

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

2014-06-20 09:51 621 查看
Proactor和Reactor都是并发编程中的设计模式。在我看来,他们都是用于派发/分离IO操作事件的。这里所谓的

IO事件也就是诸如read/write的IO操作。"派发/分离"就是将单独的IO事件通知到上层模块。两个模式不同的地方

在于,Proactor用于异步IO,而Reactor用于同步IO。

两个模式的相同点,都是对某个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类图,比较全面:



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

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一样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: