如何正确退出rector ?
mfc ace 5.5已经能够正确接受数据,单独开了个线程跑ACE_Reactor::instance()->run_reactor_event_loop();
UINT ThreadReactor(LPVOID param)
{
int result = ACE_Reactor::instance()->run_reactor_event_loop();
return 0;
}
void CAceTestDlg::OnButServer()
{
//*ACE_WFMO_Reactor 默认方式
ACE_INET_Addr port_listen(9000);
m_ClientAcceptor.reactor(ACE_Reactor::instance());
if(m_ClientAcceptor.open(port_listen) == -1)
return ;
AfxBeginThread(ThreadReactor,NULL);
}
在dia里执行end_reactor_event_loop(),也可以成功结束上面
ThreadReactor 线程。
void CAceTestDlg::OnButtonClose()
{
// TODO: Add your control notification handler code here
ACE_Reactor::instance()->end_reactor_event_loop();
}
问题1 为何ThreadReactor结束后,仍能在客户端Connect ?
问题2 如何正确退出,不引发错误 ?
出错位置
ClientAcceptor::~ClientAcceptor()
{
reactor()->remove_handler(ACE_INVALID_HANDLE,0);
}
附注:
先前代码是因为ClientAcceptor析构在ACE::fini()之后
修改后,发现 ACE::fini() 依然错误
void CAceTestDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
ACE_Reactor::instance()->owner(ACE_OS::thr_self());
ACE::fini();
CDialog::OnClose();
}
不解! 追踪到
ACE_Framework_Repository::close_singleton ();
发生错误,系内部 delete ACE_Framework_Repository::repository_; 出错
如何解决? 没有正确的进行线程同步,你必须等待ThreadReactor正常退出后,再执行关闭操作。
这类问题是使用ACE经常碰见的问题了。可以用WaitForSingleObject来处理,或者用ACE_Task来处理。 ThreadReactor 的确是正常退出的.
end_reactor_event_loop 后 run_reactor_event_loop 返回0 不这么认为,你确定那个线程退出了吗?
或者检查其它线程同步代码吧。 哦,确定退出了.
因为是在手工测试,其他地方没有线程同步的地方.
那里可以把代码传上去? 只开了一个线程
UINT ThreadReactor(LPVOID param)
{
ACE_INET_Addr port_listen(1515);
ClientAcceptor ClientAcceptor;
ClientAcceptor.reactor(ACE_Reactor::instance());
if(ClientAcceptor.open(port_listen) == -1)
return -1;
int result = ACE_Reactor::instance()->run_reactor_event_loop();
return result;
}
//启动线程
void CAceTestDlg::OnButServer()
{
AfxBeginThread(ThreadReactor,NULL);
}
//这里停止
void CAceTestDlg::OnButtonClose()
{
// TODO: Add your control notification handler code here
ACE_Reactor::instance()->end_reactor_event_loop();
}
//这里析构,略:在initDialog 里 ACE::init()
BOOL CAceTestDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
ACE_Reactor::instance()->owner(ACE_OS::thr_self());
ACE::fini();
return CDialog::DestroyWindow();
}
//Acceptor 的 handle_close
int ClientAcceptor::handle_close(ACE_HANDLE handle,ACE_Reactor_Mask close_mask)
{
if( acceptor_.get_handle()!= ACE_INVALID_HANDLE)
{
ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK|
ACE_Event_Handler::DONT_CALL;
reactor()->remove_handler(this,m);
acceptor_.close();
}
return 0;
}
//ClientService的 handle_close
int ClientService::handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask)
{
if( ACE_Event_Handler::WRITE_MASK == close_mask)
return 0;
close_mask = ACE_Event_Handler::ALL_EVENTS_MASK|ACE_Event_Handler::DONT_CALL;
reactor()->remove_handler(this,close_mask);
sock_.close();
output_queue_.flush();
delete this;
return 0;
}
注:
除了开个线程,其他均为抄书. 线程同步处理有问题,
UINT ThreadReactor(LPVOID param)
在你void CAceTestDlg::OnButtonClose()
后,不能保证立刻返回并且退出。同样,ClientService::handle_close也不能,这就是多线程抢占的特性。你必须等待额外的处理线程退出,光debug是没用的,多线程程序和网络程序有某种程度的不可调试性。
不信你在ACE::fini(); 前等待2秒钟试试。Sleep(2000); To: winston
void CAceTestDlg::OnButtonClose()这个是mfc 的函数阿。
作用是响应一个Button事件。
在这个里面执行 end_reactor_event_loop 后,
ThreadReactor就结束了
ACE::fini();是在dia 的OnClose 事件中的,要手工关闭窗口才会执行。
换而言之,关闭窗口ACE::fini()是在 ThreadReactor n久后的动作。
Sleep(2000);根本没必要,不过还是测试了一下,呵呵。没有反应
页:
[1]
2