找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5139|回复: 6

如何使异步读安全返回?ACE_OS::closesocket(this->handle());

[复制链接]
发表于 2009-5-23 00:28:38 | 显示全部楼层 |阅读模式
Proactor框架中,使用ACE_Service_Handler

当我想析构这个对象时:
~WL_Service_Handler(void)
{
....................
   m_reader.cancel();
   m_writer.cancel();
   ACE_OS::closesocket(this->handle());
   handle(ACE_INVALID_HANDLE);
   m_bCanWrite = 0;
...............
}

这样当 virtual void handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)返回时,程序就崩溃了.

看到其他一些事例,是在open函数里加入
  ACE_Sig_Action no_isgpipe((ACE_SignalHandler) SIG_IGN);
  no_isgpipe.register_action(SIGPIPE,0);
说是"禁止SIGPIPE,防止异步写终止程序"
但是如何防止异步读返回,导致程序崩溃啊?最好代码说明一下嘛,初学者,讲个理论可能不明白:handshake
 楼主| 发表于 2009-5-23 00:40:11 | 显示全部楼层
后来就想了另外一个办法,当想析构它时,绝不调用delete this,
而是调用另外一个函数:
void DeleteSelf()
{
ACE_OS::closesocket(this->handle());
   handle(ACE_INVALID_HANDLE);
}
virtual void handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)
{  
if (!result.success()
|| result.bytes_transferred() == 0)
{
delete this;
}
else
{
......
}
}
~WL_Service_Handler(void)
{
....................
   m_reader.cancel();
   m_writer.cancel();
   m_bCanWrite = 0;
...............
}
这时候,非常诡异的问题就出现了,这个事件处理器居然会从其他事件处理器抢读,
比如本地a,b,c 分别连接到服务器A,B,C,现在我按照上述的办法关闭a(调用DeleteSelf,而不是delete this)
从服务器B,C发回来的数据,居然奇异的被a抢读了,b,c只能读到一部分发回来的数据.

我想要的现实是:短连接,怎么实现呢?
 楼主| 发表于 2009-5-23 00:48:11 | 显示全部楼层
似乎问题出在怎么把这个事件处理器从Proactor里面移除,应该调用哪个函数来进行移除呢?
发表于 2009-5-23 12:41:38 | 显示全部楼层
你还没理解Proactor框架的奥妙。
Proactor框架尤其特别的地方,不仔细思考是很难发现的。
我给你找找
发表于 2009-5-23 12:51:19 | 显示全部楼层
发表于 2009-6-3 23:04:55 | 显示全部楼层
m_reader.cancel();
   m_writer.cancel();
   ACE_OS::closesocket(this->handle());
   handle(ACE_INVALID_HANDLE);
   m_bCanWrite = 0;
上面那些代码封装为一个成员函数 叫做 closeclient();
{
   if ( handle() != ACE_INVALID_HANDLE)
  {
m_reader.cancel();
   m_writer.cancel();
   ACE_OS::closesocket(this->handle());
   handle(ACE_INVALID_HANDLE);
   m_bCanWrite = 0;

}
}

2  在delete之前调用 closeclient 和析构函数里面也调用
发表于 2009-6-26 14:32:42 | 显示全部楼层
楼主的用法比较罕见,多线程跑多个proactor实例。。
还有,也不用每个线程一个connector,共用一个就行。
很多人容易把线程和对象搞混。一个是静态的对象一个是动态的执行概念。

个人意见,client端没必要用proactor,异步方式开发成本相对较高,能用清晰的同步方式最好。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-12-23 17:51 , Processed in 0.016514 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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