两个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 一下下