一、概念:

Reactor与Proactor两种模式的区别。这里我们只关注read操作,因为write操作也是差不多的。下面是Reactor的做法:

  1. 某个事件处理器宣称它对某个socket上的读事件很感兴趣;

  2. 事件分离者等着这个事件的发生;

  3. 当事件发生了,事件分离器被唤醒,这负责通知先前那个事件处理器;

  4. 事件处理器收到消息,于是去那个socket上读数据了. 如果需要,它再次宣称对这个socket上的读事件感兴趣,一直重复上面的步骤;

下面再来看看真正意义的异步模式Proactor是如何做的:

  1. 事件处理器直接投递发一个读操作(当然,操作系统必须支持这个异步操作)。这个时候,事件处理器根本不关心读事件,它只管发这么个请求,它魂牵梦萦的是这个读操作的完成事件。这个事件处理器很拽,发个命令就不管具体的事情了,只等着别人(系统)帮他搞定的时候给他回个话。

  2. 事件分离器等着这个读事件的完成(比较下与Reactor的不同);

  3. 当事件分离器默默等待完成事情到来的同时,操作系统已经在一边开始干活了,它从目标读取数据,放入用户提供的缓存区中,最后通知事件分离器,这个事情我搞完了;

  4. 事件分离器通知之前的事件处理器: 你吩咐的事情搞定了;

  5. 事件处理器这时会发现想要读的数据已经乖乖地放在他提供的缓存区中,想怎么处理都行了。如果有需要,事件处理器还像之前一样发起另外一个读操作,和上面的几个步骤一样。

二、代码示例:

ACE_Proactor::run_event_loop();  循环启动
ACE_Proactor::end_event_loop();  循环停止

-----------------------------------

Reactor:

-----------------------------------

-----------------------------------

Proactor:

 #include "ace/Proactor.h"
#include "ace/Asynch_Acceptor.h" class HA_Proactive_Service : public ACE_Service_Handler
{
public:
HA_Proactive_Service()
{
ACE_OS::printf("Service_Handler constructed for accepter \n");
}
~HA_Proactive_Service ()
{
if (this->handle () != ACE_INVALID_HANDLE)
{
ACE_OS::closesocket (this->handle ());
}
} virtual void open (ACE_HANDLE h, ACE_Message_Block&)
{
//在OPEN函数中完成读写操作
this->handle (h);
if (this->reader_.open (*this) != ||
this->writer_.open (*this) != )
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("HA_Proactive_Service open"))); return;
}
ACE_OS::printf("ready!\n"); //异步发送
send_to_remote();
//异步读取
reveive_from_remote(); // mb is now controlled by Proactor framework.
return;
} //异步读完成后会调用此函数
virtual void handle_read_stream
(const ACE_Asynch_Read_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block ();
if (!result.success () || result.bytes_transferred () == )
{
mb.release (); return;
}
//else
//输出读取内容
ACE_OS::printf("received:%s\n",mb.rd_ptr());
mb.release();
//继续下一次异步读取
reveive_from_remote(); return;
}
//异步写完成后会调用此函数
virtual void handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
{
result.message_block ().release();
ACE_OS::sleep();
//上次发送完毕之后再接着发送一次,这次发送完成之后又会调用
//handle_write_stream,所以会一直发送
send_to_remote();
return;
}
//remote
void reveive_from_remote(void)
{
ACE_Message_Block *mb;
ACE_NEW_NORETURN (mb, ACE_Message_Block ());
if (this->reader_.read (*mb, mb->space ()) != )
{
ACE_OS::printf("Begin read fail\n"); return;
}
}
//把当前时间发送到远端
void send_to_remote(void)
{
std::string book = "S: ";
time_t now = ACE_OS::gettimeofday().sec();
book = book+ ctime(&now);
ACE_Message_Block *mb = new ACE_Message_Block();
//获取当前时间的字符串格式
mb->copy(book.c_str() );
//send message to accepter
if (this->writer_.write(*mb,mb->length()) !=)
{
ACE_OS::printf("Begin write fail\n"); return;
}
else
{
ACE_OS::printf("sended %s\n",mb->rd_ptr());
}
} // Listing 3
private:
ACE_Asynch_Read_Stream reader_;
ACE_Asynch_Write_Stream writer_;
}; int main(int argc, char *argv[])
{
int port=;
ACE_Asynch_Acceptor<HA_Proactive_Service> acceptor; if (acceptor.open (ACE_INET_Addr (port)) == -)
return -; while(true)
ACE_Proactor::instance ()->handle_events (); return ;
}

Acceptor.cpp

 #include "ace/Proactor.h"
#include "ace/Asynch_Connector.h" class HA_Proactive_Service : public ACE_Service_Handler
{
public:
HA_Proactive_Service()
{
ACE_OS::printf("Service_Handler constructed for connector \n");
}
~HA_Proactive_Service ()
{
if (this->handle () != ACE_INVALID_HANDLE)
{
ACE_OS::closesocket (this->handle ());
}
} virtual void open (ACE_HANDLE h, ACE_Message_Block&)
{
//在OPEN函数中完成读写操作
this->handle (h); if (this->reader_.open (*this) != ||
this->writer_.open (*this) != )
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("HA_Proactive_Service open"))); return;
} ACE_OS::printf("connceted!\n");
//异步发送
send_to_remote();
//异步读取
reveive_from_remote(); return;
} //异步读完成后会调用此函数
virtual void handle_read_stream
(const ACE_Asynch_Read_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block ();
if (!result.success () || result.bytes_transferred () == )
{
mb.release (); return;
}
//else
//输出读取内容
ACE_OS::printf("received:%s\n",mb.rd_ptr());
mb.release();
//继续下一次异步读取
reveive_from_remote(); return;
}
//异步写完成后会调用此函数
virtual void handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
{
result.message_block ().release();
ACE_OS::sleep();
//上次发送完毕之后再接着发送一次,这次发送完成之后又会调用
//handle_write_stream,所以会一直发送
send_to_remote();
return;
}
//remote
void reveive_from_remote(void)
{
ACE_Message_Block *mb;
ACE_NEW_NORETURN (mb, ACE_Message_Block ());
if (this->reader_.read (*mb, mb->space ()) != )
{
ACE_OS::printf("Begin read fail\n"); return;
}
}
//把当前时间发送到远端
void send_to_remote(void)
{
std::string book = "C: ";
time_t now = ACE_OS::gettimeofday().sec();
book = book+ ctime(&now);
ACE_Message_Block *mb = new ACE_Message_Block();
//获取当前时间的字符串格式
mb->copy(book.c_str() );
//send message to accepter
if (this->writer_.write(*mb,mb->length()) !=)
{
ACE_OS::printf("Begin write fail\n"); return;
}
else
{
ACE_OS::printf("sended %s\n",mb->rd_ptr());
}
} // Listing 3
private:
ACE_Asynch_Read_Stream reader_;
ACE_Asynch_Write_Stream writer_;
}; int main(int argc, char *argv[])
{ ACE_INET_Addr addr(,"127.0.0.1"); ACE_Asynch_Connector<HA_Proactive_Service> connector; connector.open();
if (connector.connect(addr) == -)
return -; while(true)
ACE_Proactor::instance ()->handle_events (); return ;
}

Connector.cpp

ACE_Proactor::run_event_loop(); <==>
while(true)
    ACE_Proactor::instance ()->handle_events ();

//增加线程池

 #include "ace/Proactor.h"
#include "ace/Asynch_Acceptor.h"
#include "ace/Task_T.h"
#include "ace/Thread_Semaphore.h" class Receive : public ACE_Service_Handler
{
public:
Receive()
{
ACE_OS::printf("Service_Handler constructed for accepter \n");
}
~Receive ()
{
if (this->handle () != ACE_INVALID_HANDLE)
{
ACE_OS::closesocket (this->handle ());
}
} virtual void open (ACE_HANDLE h, ACE_Message_Block&)
{
//在OPEN函数中完成读写操作
this->handle (h);
if (this->reader_.open (*this) != ||
this->writer_.open (*this) != )
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("Receive open"))); return;
}
ACE_OS::printf("ready!\n"); //异步发送
//send_to_remote();
//异步读取
reveive_from_remote(); // mb is now controlled by Proactor framework.
return;
} //异步读完成后会调用此函数
virtual void handle_read_stream
(const ACE_Asynch_Read_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block ();
if (!result.success () || result.bytes_transferred () == )
{
mb.release (); return;
} //输出读取内容
//ACE_OS::printf("received:%s\n",mb.rd_ptr());
ACE_DEBUG((LM_DEBUG,"(%t)received:%s\n",mb.rd_ptr()));
mb.release(); //继续下一次异步读取
reveive_from_remote(); return;
}
//异步写完成后会调用此函数
virtual void handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
{
result.message_block ().release();
ACE_OS::sleep();
//上次发送完毕之后再接着发送一次,这次发送完成之后又会调用
//handle_write_stream,所以会一直发送
send_to_remote();
return;
}
//remote
void reveive_from_remote(void)
{
ACE_Message_Block *mb;
ACE_NEW_NORETURN (mb, ACE_Message_Block ());
if (this->reader_.read (*mb, mb->space ()) != )
{
ACE_OS::printf("Begin read fail\n"); return;
}
}
//把当前时间发送到远端
void send_to_remote(void)
{
std::string book = "S: ";
time_t now = ACE_OS::gettimeofday().sec();
book = book+ ctime(&now);
ACE_Message_Block *mb = new ACE_Message_Block();
//获取当前时间的字符串格式
mb->copy(book.c_str() );
//send message to accepter
if (this->writer_.write(*mb,mb->length()) !=)
{
ACE_OS::printf("Begin write fail\n"); return;
}
else
{
ACE_OS::printf("sended %s\n",mb->rd_ptr());
}
} // Listing 3
private:
ACE_Asynch_Read_Stream reader_;
ACE_Asynch_Write_Stream writer_;
}; class Accepte : public ACE_Asynch_Acceptor<Receive>
{
public:
virtual Receive* make_handler(void)
{
return new Receive();
} }; class Proactor_Task : public ACE_Task<ACE_MT_SYNCH>
{
public: int star(int nMax)
{
create_proactor();
this->activate (THR_NEW_LWP, nMax);
for (;nMax>;nMax--)
{
sem_.acquire();
}
return ;
}
int stop()
{
ACE_Proactor::end_event_loop();
this->wait();
return ;
} virtual int svc (void)
{
ACE_DEBUG((LM_INFO,ACE_TEXT("svc method is invoked!\n")));
sem_.release(); ACE_Proactor::run_event_loop(); return ;
} int create_proactor()
{
ACE_Proactor::instance (); return ;
} int release_proactor()
{
ACE_Proactor::close_singleton ();
return ;
} ACE_Thread_Semaphore sem_;
}; int ACE_TMAIN(int ,char*[])
{
Proactor_Task task;
task.star(); Accepte accepte;
accepte.open(ACE_INET_Addr (), , ,ACE_DEFAULT_BACKLOG,,ACE_Proactor::instance()); //主函数退出控制
{
int nExit=;
while (nExit==)
scanf("%d",&nExit);
} return ;
} /*
int main(int argc, char *argv[])
{
int port=3000;
ACE_Asynch_Acceptor<Receive> acceptor; if (acceptor.open (ACE_INET_Addr (port)) == -1)
return -1; ACE_Proactor::run_event_loop(); return 0;
}
*/

Proactor_Task.cpp

-----------------------------------

GOOD LUCK!

ACE_linux:Reactor与Proactor两种模式的区别的更多相关文章

  1. 【转】Reactor与Proactor两种模式区别

    转自:http://www.cnblogs.com/cbscan/articles/2107494.html 两种IO多路复用方案:Reactor and Proactor 一般情况下,I/O 复用机 ...

  2. vue-router的两种模式的区别

    众所周知,vue-router有两种模式,hash模式和history模式,这里来谈谈两者的区别. ### hash模式 hash模式背后的原理是`onhashchange`事件,可以在`window ...

  3. 在IDEA中将项目部署到Tomcat的方法及两种模式的区别

    转自:https://www.jianshu.com/p/fb0ed26c35d5 1.添加tomcat服务器 点右上角编辑配置   编辑配置 点击左上角+选择tomcat服务器   添加tomcat ...

  4. MODBUS ASCII和RTU两种模式的区别、优缺点

    转自:http://blog.sina.com.cn/s/blog_89f286ad0102uzju.html 下表是MODBUS ASCII协议和RTU协议的比较: 协议 开始标记 结束标记 校验 ...

  5. vue-router 的两种模式的区别

    Vue Router 是Vue官方的路由管理器.它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌.vue-router 默认 hash 模式,还有一种是history模式. hash模 ...

  6. vue-router两种模式的区别

    参考文献:https://blog.csdn.net/lla520/article/details/77894985/ https://segmentfault.com/a/1190000015123 ...

  7. Unity下Iso和Persp两种模式的区别

    Iso模式 平行视野.在Iso模式下,不论物体距离摄像头远近都给人的感觉是一样大的. Persp模式 透视视野.在persp模式下,物体在scene界面上所呈现的画面是给人一种距离摄像头近的物体显示的 ...

  8. Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程

    Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明: Reactor实现架构对比 面向对象的设计类图如下: 函数式编程以muduo为例 ...

  9. Windows2003 IIS6.0支持32位和64位两种模式的设置方法

    IIS 6.0 可支持 32 位和 64 位两种模式.但是,IIS 6.0 不支持在 64 位版本的 Windows 上同时运行这两种模式.ASP.NET 1.1 只在 32 位模式下运行.而 ASP ...

随机推荐

  1. CISCO 双线接入MAP配置详解

      随着我国宽带技术的普及,各个公司都会有一至二条Internet接入线路,这些线路可能由电信.网通.长宽.联通等不同的IS提供,尽管他们在局端采用的技术可能有不同,但对客户而言都是同样接入方式,以太 ...

  2. ajax生成html双引号问题

    //动态创建列表 function createLists(result){ var len=result.length,i; for(i=0;i<len;i++){ $myLi = $(&qu ...

  3. PHP.8-HTML+CSS(二)-HTML详解

    HTML+CSS HTML参考手册[http://www.w3school.com.cn/tags/index.asp] 0.HTML主体标记 代码分为三部分编写 <html> 是网页文件 ...

  4. DataBase 之 实用积累

    (1)分页:(性能效果最好的是top/max 和Row_number()两种方法) [1]写法1,not in/top select top pagesize * from pagetest wher ...

  5. Java中的Scoket编程

    网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net包中提供了两种常见的网络协议的支持: TCP: TCP是传输控制协议的缩写,它保障了两个应用程序之间的可靠 ...

  6. TCP/IP协议原理与应用笔记19:IP分组的交付和路由选择

    1. 引言: (1)互联网结构: 信息:IP分组(直接广播地址(Directed Broadcast Address),其指定了在一个特定网络中的"所有主机".) 节点:路由器.主 ...

  7. 字体的大小(pt)和像素(px)如何转换?

    px:相对长度单位.像素(Pixel). pt:绝对长度单位.点(Point). 1in = 2.54cm = 25.4 mm = 72pt = 6pc 具体换算是: Points Pixels Em ...

  8. js工作中编程习惯

    在前端编程中总结的习惯不管js还是css 还是后端开发这几点都是必须要做到的做好这几点不管去什么公司都是受到别人的尊重 善用变量,尤其是对DOM结构中的ID以及CLASS 多写注释,自己不熟,前面写后 ...

  9. DHCP服务详解

    DHCP概念和原理 dhcp服务作用 为大量客户机自动分配地址,提供集中管理 减轻管理和维护成本,提高网络配置效率 可分配的地址信息主要包括: 网卡的IP地址.子网掩码 对应的网络地址 默认网关地址 ...

  10. Oracle_11g中解决被锁定的scott用户的方法(转载)

    转自:http://www.2cto.com/database/201402/277206.html Oracle 11g中修改被锁定的用户:scott 在安装完Oracle11g和创建完oracle ...