找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4071|回复: 2

连接-接入模式中每个对应client能不能新申请一个反应器?

[复制链接]
发表于 2007-12-11 22:07:55 | 显示全部楼层 |阅读模式
在server端派生自ACE_Svc_Handler写对应Client的处理类ServerClient
有人说如果ServerClient开线程,因为默认ServerClient与ACE_Acceptor是同一个单体的反应器,所以在ServerClient线程中写的话就会出现分别在2个线程里读 写,于是需要同步访问ServerClient的sock_stream,
我的问题就是
确实需要同步吗?
假设需要同步,于是打算把ServerClient的读与写都放在自己的线程里:重载ServerClient的open函数重新申请一个反应器.
该怎么申请呢?
我简单尝试了一下在ServerClient中组合了一个反应器,但是在ServerClient的handler_close中delete this总是报错,似乎是新定义的反映器出错(我保证handler_close只被调用了一次)
完整的代码贴上,大家帮调试一下:
Server端:
  1. #include <ace/Reactor.h>
  2. #include <ace/Svc_Handler.h>
  3. #include <ace/Acceptor.h>
  4. #include <ace/sock_stream.h>
  5. #include <ace/Acceptor.h>
  6. #include <ace/SOCK_Acceptor.h>
  7. #include <iostream>
  8. using std::cout;
  9. using std::endl;
  10. class CSvcHandler :public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>
  11. {
  12. public:
  13. CSvcHandler(void);
  14. public:
  15. ~CSvcHandler(void);
  16. public:
  17.   int handle_input(ACE_HANDLE);
  18.   int handle_close (ACE_HANDLE handle ,ACE_Reactor_Mask colse_mask);
  19.   int open(void*);
  20.   int svc();
  21. private:
  22. ACE_Reactor* m_pobjReactor;
  23.     char data[1024];
  24. };
  25. CSvcHandler::CSvcHandler(void)
  26. {
  27. cout<<"Acceptor ClientPoint:I'm coming.\n"<<endl;
  28. m_pobjReactor = new ACE_Reactor();
  29. }
  30. CSvcHandler::~CSvcHandler(void)
  31. {
  32. cout<<"Acceptor ClientPoint:I'm out.\n";
  33. delete m_pobjReactor;
  34. }
  35. int CSvcHandler::handle_input(ACE_HANDLE)
  36. {
  37. memset(data,0,sizeof(data));
  38. int rev = peer().recv(data,sizeof(data) - 1);
  39. if(rev < 1)
  40. {
  41.   return -1;
  42. }
  43. else
  44. {
  45.   cout<<"Acceptor ClientPoint recv:"<<data<<endl<<"and return:"<<data<<endl<<endl;
  46.   peer().send(data,sizeof(data) - 1);
  47.   return 0;
  48. }
  49. }
  50. int CSvcHandler::handle_close (ACE_HANDLE handle ,ACE_Reactor_Mask colse_mask)
  51. {
  52. cout<<"Acceptor ClientPoint:handle_close\n";
  53. delete this;
  54. return 0;
  55. }
  56. int CSvcHandler:pen(void*)
  57. {
  58. reactor(m_pobjReactor);
  59. m_pobjReactor->register_handler(this,  ACE_Event_Handler::READ_MASK);
  60. activate();
  61. return 0;
  62. }
  63. int CSvcHandler::svc()
  64. {
  65. while(true)
  66. {
  67.   m_pobjReactor->handle_events();
  68. }
  69. return 0;
  70. }
  71. int _tmain(int argc, _TCHAR* argv[])
  72. {
  73. ACE_INET_Addr l_objLocalAddr(3000,"127.0.0.1");
  74. ACE_Acceptor<CSvcHandler,ACE_SOCK_ACCEPTOR> l_objAcceptor;
  75. l_objAcceptor.open(l_objLocalAddr);
  76. while(1)
  77. {
  78.   ACE_Reactor::instance()->handle_events();
  79. }
  80. return 0;
  81. }
  82. _________________________________
  83. Client端:
  84. #include <ace/SOCK_Connector.h>
  85. #include <ace/Connector.h>
  86. #include <ace/Reactor.h>
  87. #include <ace/Svc_Handler.h>
  88. #include <ace/Acceptor.h"
  89. #include <ace/sock_stream.h>
  90. #include <iostream>
  91. using std::cout;
  92. using std::endl;
  93. class CSvcHandler :public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>
  94. {
  95. public:
  96. CSvcHandler(void);
  97. public:
  98. ~CSvcHandler(void);
  99. public:
  100.   int handle_input(ACE_HANDLE);
  101.   int handle_close (ACE_HANDLE handle ,ACE_Reactor_Mask colse_mask);
  102. private:
  103.     char data[1024];
  104. };
  105. CSvcHandler::CSvcHandler(void)
  106. {
  107. cout<<"Connector ClientPoint:I'm coming.\n"<<endl;
  108. }
  109. CSvcHandler::~CSvcHandler(void)
  110. {
  111. cout<<"Connector ClientPoint: I'm out.\n";
  112. }
  113. int CSvcHandler::handle_input(ACE_HANDLE)
  114. {
  115. memset(data,0,sizeof(data));
  116. int rev = peer().recv(data,sizeof(data) - 1);
  117. if(rev < 1)
  118. {
  119.   return -1;
  120. }
  121. else
  122. {
  123.   cout<<"Connector ClientPoint recv:"<<data<<endl;
  124.   return 0;
  125. }
  126. }
  127. int CSvcHandler::handle_close (ACE_HANDLE handle ,ACE_Reactor_Mask colse_mask)
  128. {
  129. cout<<"Connector ClientPoint:handle_close\n";
  130. delete this;
  131. return 0;
  132. }
  133. int _tmain(int argc, _TCHAR* argv[])
  134. {
  135. ACE_INET_Addr l_objRemoteAddr(3000,"127.0.0.1");
  136. CSvcHandler* l_pobjClientPoint = new CSvcHandler();
  137. ACE_Connector<CSvcHandler,ACE_SOCK_CONNECTOR> l_objConnector;
  138. l_objConnector.connect(l_pobjClientPoint,l_objRemoteAddr);
  139. char l_szBuffer[64] = "C-A模式";
  140. int l_nSize = l_pobjClientPoint->peer().send(l_szBuffer,sizeof(l_szBuffer));
  141. cout<<"Connector ClientPoint send:"<<l_szBuffer<<endl;
  142. while(true)               
  143. {
  144.   ACE_Reactor::instance()->handle_events();
  145. }
  146. delete l_pobjClientPoint;
  147. return 0;
  148. }
复制代码

[ 本帖最后由 peakzhang 于 2007-12-11 22:17 编辑 ]
 楼主| 发表于 2007-12-11 22:08:26 | 显示全部楼层
一堆问题:
你怎么确保在删除对象的时候,对象已经停止运行?

CSvcHandler::~CSvcHandler(void)
{
cout<<"Acceptor ClientPoint:I'm out.\n";
delete m_pobjReactor;

}


int CSvcHandler::svc()
{
while(true)
{
  m_pobjReactor->handle_events(); //同步呢?
}

return 0;

}
你退出的时候,要删除m_pobjReactor,你怎么保证删除的时候,它已经停止运行了。
发表于 2007-12-12 16:54:03 | 显示全部楼层
ServerClient开线程的方式为:
1在open方法中调用activate方法启动多个处理线程.
2在handle_input方法中,将从网络接收到的数据调用put方法,加入到消息队列中
3在svc中,不停地getq,以取得接收到的消息,消息内容可以包括具体的接收数据,接收socket的句柄(便于向客户端发送应答数据)
4svc中接收到退出消息时,退出线程.因此在handle_close方法中,要发送n(激活的工作线程的个数)个退出消息,并调用wait方法,等待所有工作线程退出.
在这里,只是消息的处理是多线程的,数据的接收和发送用的是主线程的Reactor.
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-23 19:03 , Processed in 0.014104 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表