找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 10599|回复: 15

proactor与MFC的使用问题

[复制链接]
发表于 2008-7-13 23:25:23 | 显示全部楼层 |阅读模式
我在MFC中使用Proactor,把连接语句放在了线程函数中,接下来就是运行事件循环(因为客户端需要好几个连接,而每个连接又要单独控制,所以连接时传入了一个new的Proactor指针,以便在处理类中通过this->proactor()->proactor_end_event_loop()来结束该连接对应的事件循环,从而关闭连接线程)。连接线程函数如下:
void * CPro_mfc_serverDlg::TransFile_SenderProc(void * szServerIP)
{
CString Ip=*((CString *)szServerIP);
ACE_Proactor *p1=new ACE_Proactor;
ACE_Proactor::instance(p1, 1);
ACE_INET_Addr addr(LISTEN_PORT2,Ip);
ACE_Asynch_Connector<TransFile_Sender> connector;
if (connector.open (1, p1, 1) != 0)
{
  AfxMessageBox("Connector::open failed");
  delete p1;
  return 0;
}
if(connector.connect(addr)==-1)
{
  AfxMessageBox("Connection failed");
  delete p1;
  return 0;
}
ACE_Proactor::instance()->proactor_reset_event_loop(); //重新启动事件循环
ACE_Proactor::instance()->proactor_run_event_loop();
delete p1;
AfxMessageBox("发送线程关了");   //测试用
return 0;
}
线程开启语句
ACE_Thread::spawn((ACE_THR_FUNC)TransFile_SenderProc,(void *)&m_Server_IP,THR_DETACHED,&t_id); //开辟发送文件线程
现在的问题是:
如果在该连接的处理类的析构中用this->proactor()->proactor_end_event_loop();关闭了对应的事件循环,线程会正确关闭,此时也没有错误,但在程序关闭时运行ACE::fini();释放资源时会出现错误(发送不发送的那种错误),如果隐掉ACE::fini();则没有什么错误,但心里不踏实,因为MFC程序必须要调用ACE::fini();
如果在连接处理类的析构中不停止对应的事件循环,那么在关闭时调用ACE::fini();释放资源不会有错误发生,但这样的话由于没有结束循环,连接线程就不会关闭。不知这样的问题如何解决?
 楼主| 发表于 2008-7-13 23:25:29 | 显示全部楼层
几个问题:
1、貌似你理解Proactor有问题?所有的网络连接处理,其实都可以共享一个ACE_Proactor::instance()。不要一个连接一个Proactor,是错误的方式。Proactor是框架。
2、不要在析构函数中调用结束接口。道理是,ACE里面有层层的派生关系,你在析构中调用,可能导致对象已经析构了,却还要调用,导致崩溃。直接调用。
最好上传完整代码,否则我们只是猜测。
 楼主| 发表于 2008-7-13 23:25:36 | 显示全部楼层
所有的网络连接处理,其实都可以共享一个ACE_Proactor::instance()。不要一个连接一个Proactor,是错误的方式。Proactor是框架。
----------------------------------------

要是都用一个实例的话,每个开启的线程怎么关闭,因为只要调用结束循环的语句,所有的线程就都会因为循环结束而关闭,这样是不行的。因为我想实现同时传输多个文件的功能,所以想一个传输建一个连接.不这样怎么实现呢?您说的第二个问题:不要在析构中调用结束接口,那在哪里调用结束循环语句呢?总得结束吧,结束了才能关闭线程阿
 楼主| 发表于 2008-7-13 23:25:43 | 显示全部楼层
一般来说,一个EXE用一个PROACTOR就可以,你可以单独写一个类把PROACTOR包装进去,再添加其成员函数来启动和关闭PROACTOR。我觉得楼主的程序架构不是很合理哟~_~
 楼主| 发表于 2008-7-13 23:25:50 | 显示全部楼层
感觉你对Proactor缺乏理解。
只有在程序最终结束的时候,才需要调用ACE_Proactor::instance()->proactor_end_event_loop();
另外,Proactor中,一个连接是一个处理器对象,传输完毕,直接关闭这个对象就可以了,不能关闭Proactor框架,更不需要一个连接一个线程这样低效的方式。
 楼主| 发表于 2008-7-13 23:25:56 | 显示全部楼层
Proactor中,一个连接是一个处理器对象,传输完毕,直接关闭这个对象就可以了,不能关闭Proactor框架,更不需要一个连接一个线程这样低效的方式

----------------------------------

我知道一个连接一个处理器对象,所以在服务器端就不必这样,因为它是被动连接,而客户端不主动发起的话,怎么产生连接?不产生连接怎么分配处理器对象,这正是我不解的地方。
 楼主| 发表于 2008-7-13 23:26:03 | 显示全部楼层
客户端连接的时候,才产生处理器对象,参考异步的Acceptor实现。产生了处理器对象,就可以发起异步的读写操作,直到最终关闭连接,再删除这个处理器对象。不需要一个连接一个线程。
 楼主| 发表于 2008-7-13 23:26:08 | 显示全部楼层
可在MFC中事件循环语句好像必须放在线程中才能运行阿,要不然程序运行到那里就停住了。如果要同时传输多个文件,用一个连接恐怕不行吧。那个连接线程函数,前边部分可以不放到线程,可事件循环不行的,总不能每个连接用一个事件循环吧?再说怎么用呢
 楼主| 发表于 2008-7-13 23:26:14 | 显示全部楼层
事件循环当然要在额外的线程中运行,可是只需要运行一次啊。
所有的连接处理都可以共享这个Proactor事件循环,而不是每个连接创建一个。
 楼主| 发表于 2008-7-13 23:26:21 | 显示全部楼层
不行的,我试过了,我在线程中只放入了事件循环的语句,将连接语句没有放在里边,在按钮“连接”中写上连接语句,然后运行线程函数,连接不上。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-11-23 16:04 , Processed in 0.016962 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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