首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

两个ACE的奇怪有关问题

2012-02-29 
两个ACE的奇怪问题1. register_handler竟然触发handle_close()?有多个ACE_Task对象, 在每个对象的一个线程

两个ACE的奇怪问题
1. register_handler竟然触发handle_close()?


有多个ACE_Task对象, 在每个对象的一个线程里,调用
register_handler(p_connect_handler_, ACE_Event_Handler::READ_MASK);

从第二个ACE_Task对象调用reactor_.register_handler(p_connect_handler_, ACE_Event_Handler::READ_MASK);开始

都会触发两个handle_close事件, 大家碰到过没?而且调用线程handle_close()的线程我都找不到!

=========================================================================================
2. ACE_Message_Queue的问题。
我在连接器(继承自public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>)的handle_input里 新建一个Block并添加到ACE_Message_Queue队列的队尾:
  // …… , 新建buf数据, 没有问题。
  // 将填好的应答消息包发给前端应用服务器
  ACE_Message_Block *mb = NULL;
  ACE_NEW_RETURN(mb, ACE_Message_Block(sizeof(***)), 0);
  mb->copy(buf, sizeof(***));
   
  if(-1 == send_queue_.enqueue_tail(mb))
  {
  ACE_DEBUG((LM_ERROR, ACE_TEXT("(%P|%t) putq error, errno: %d.\n"), ACE_OS::last_error()));
  mb->release();
  }

在该连接器创建的的发送线程里

int ***::send_thread()
{
  while(true)
  {
  ACE_Message_Block *mb = NULL;
  if(-1 == send_queue_.dequeue_head(mb))
  {
  ACE_DEBUG((LM_INFO, ACE_TEXT("(%P|%t) dequeue error, errno: %d\n"), ACE_OS::last_error()));
  break;
  }
  int dataLen = mb->size();
  //…… 主机地址转成网络地址
  ACE_Time_Value tv(10, 0);
  if(dataLen != peer().send_n(mb->base(), dataLen, &tv))
  {
  ACE_DEBUG((LM_INFO, ACE_TEXT("(%P|%t) Send error, errno: %d\n"), ACE_OS::last_error()));
  break;
  }
  mb->release();
  mb = NULL;
  }
  return 0;
}

=====================================
连接器在不同的线程内实例化。在第一个线程的handle_input里添加到消息队列(send_queue_)的mb可以在send_thread函数里发送出去, 而第二个线程的handle_input里添加到消息队列的mb就不能从对了中取出mb.

[解决办法]
顶呀顶呀顶呀顶
[解决办法]
是不是你消息队列的同步问题?
[解决办法]
帮顶一下
[解决办法]
1.第一个问题,不知所云。。。,
你给的信息不够,我的理解是:
如果你的handle_*函数返回-1的话,是主线程去调用的handle_close。
就是run_reactor_event_loop那个线程。
否则,就是你自己调用remove_handler,并且remove的时候没有加DONT_CALL标记,然后就调用handle_close。

2.“连接器(继承自public ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_MT_SYNCH> )的handle_input里”,不太明白,连接器是connector,你重写人家ACE_Connector的handle_input了?
从代码上看,不知道send_queue_是所有连接共用的queue,还是每个handler一个?是所有线程公用一个queue,
还是每个线程一个?
ACE_Svc_Handler本身是有个queue的。
你可能想实现的是:收到信息后,送进队列处理,处理完成后再发送,所以,
你在这里不能注册WRITEMASK,但是又不知道如何发送。

如果是这样,建议你看下队列的通知机制。
用ACE_Reactor_Notification_Strategy类和ACE_Svc_Handler类结合,可以实现你的功能。
ACE已经提供这个功能,没必要搞成你写的这么复杂。


[解决办法]
个人感觉ACE把那几个例子搞一搞就完事了,太深了就要研究源代码了。
线程池 TCP UDP server 那几种模式 都有现成代码。
貌似没别的用了
现在感觉不错的就是ACE那个基于MMAP的HASH TABLE。
别的没啥稀奇的。
[解决办法]
int k_net_tcp_dealer::send_mb( ACE_Message_Block * mb )
{
if( mb == NULL ) return 0;



if( m_del_flag )
return -1;

bool empty = msg_queue()->is_empty();
ACE_Time_Value tm( 1, 0 );
if( putq( mb, &tm ) == -1 )
{
return -1;
}

if( !empty )
{
empty = msg_queue()->message_count() == 1;
}
if( empty )
{

tm.set( 1, 0 );
reactor()->notify( this, ACE_Event_Handler::WRITE_MASK, &tm );
}

return 0;

}
举个例子,可以添加,然后触发write事件,再写数据.
[解决办法]
up 一下下

热点排行