问题描述
|后,Poco HTTPServer连接仍然可用。
我在使用Poco :: HTTPServer时遇到问题。如Tcpserver文档中所述:
调用stop()后,将不接受任何新连接,并且所有
排队的连接将被丢弃。已提供连接,
但是,将继续提供。
每个连接都在其自己的线程中执行。
尽管似乎成功地调用了析构函数,但连接线程仍然存在并为连接提供服务,这会导致分段错误。
我想取消所有连接。因此,我在服务器类的析构函数中使用了“ 0”,这导致ThreadPool的文档中也描述了这种行为(这需要10秒钟,并且不会删除对象):
如果线程未能在10秒内停止(由于编程)
错误,例如),基础线程对象将不会被删除
并且此方法仍会返回。这或多或少
如果出现异常线程,请正常关闭。
我的问题是:如何完成更优美的方式? Poco库中是否存在编程错误?
编辑:我使用GNU / Linux(Ubuntu 10.04)和eclipse + cdt作为IDE,目标系统是嵌入式Linux(内核2.6.9)。在两个系统上,我都经历了所描述的行为。
我正在处理的应用程序应通过Web界面进行配置。因此,服务器将事件(在上传新配置时)发送给main以重新启动。
这是大纲:
main{
while (true){
server = new Server(...);
server->start();
// wait for termination request
server->stop();
delete server;
}
}
class Server{
Poco:HTTPServer m_Server;
Server(...):
m_Server(requestHandlerFactory,socket,params);
{
}
~Server(){
[...]
Poco::ThreadPool::defaultPool().stopAll(); // This takes 10 seconds!
// without the above line I get segmentation faults,// because connections are still being served.
}
start() { m_Server.start(); }
stop() { m_Server.stop(); }
}
解决方法
这实际上是stopAll()方法的实现中的错误。关闭当前活动的连接后,正在关闭侦听套接字,这使服务器可以接受介于两者之间的新连接,而新连接又不会关闭并保持运行。解决方法是先调用HTTPServer :: stop(),然后再调用HTTPServer :: stopAll()。我在上游报告了该错误,其中包括一个建议的修复程序:
https://github.com/pocoproject/poco/issues/436
, 您应避免使用
Poco::ThreadPool::defaultPool().stopAll();
,因为它无法控制停止线程。
我建议您专门为您的“ 4”实例创建一个“ 3”实例,并在服务器停止时停止该池的线程。
这样,您的代码应如下所示:
class Server{
Poco:HTTPServer m_Server;
Poco::ThreadPool m_threadPool;
Server(...)
: m_Server(requestHandlerFactory,m_threadPool,socket,params);
{
}
~Server(){
}
start() { m_Server.start(); }
stop() {
m_Server.stop();
m_threadPool.stopAll(); // Stop and wait serving threads
}
};
对于发布者来说,这个答案可能为时已晚,但是由于该问题帮助我解决了我的问题,因此我认为在此处发布解决方案很好!