我在使用Poco :: HTTPServer时遇到问题。正如TCPServer的文档中所描述的那样:
调用stop()后,不会接受任何新连接 排队的连接将被丢弃。已经提供连接, 但是,将继续服务。
每个连接都在自己的线程中执行。 虽然似乎析构函数被成功地称为连接线程仍然存在并提供连接,这会导致分段错误。
我想取消所有连接。因此,我在我的服务器类的析构函数中使用Poco::ThreadPool::defaultPool().stopAll();
,这导致了ThreadPool文档中描述的行为(它需要 10秒并且对象不会被删除):
如果线程在10秒内未能停止(由于编程 例如,错误,不会删除底层线程对象 而且这种方法无论如何都会返回。这允许或多或少 在行为不当的情况下正常关机。
我的问题是:我如何实现更优雅的方式? Poco库中是否存在编程错误?
编辑:我使用GNU / Linux(Ubuntu 10.04)和eclipse + cdt作为IDE,目标系统是嵌入式Linux(Kernel 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(); }
}
答案 0 :(得分:6)
这实际上是stopAll()方法实现中的一个错误。关闭当前活动连接后,侦听套接字正在关闭,这允许服务器接受其间的新连接,而这些连接又不会关闭并继续运行。解决方法是调用HTTPServer :: stop(),然后调用HTTPServer :: stopAll()。我报告了上游的错误,包括一个建议的修复:
答案 1 :(得分:0)
您应该避免使用Poco::ThreadPool::defaultPool().stopAll();
,因为它无法控制哪些线程停止。
我建议您专门为Poco::ThreadPool
实例创建Poco:HTTPServer
,并在服务器停止时停止此池的线程。
有了这个,你的代码应该是这样的:
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
}
};
这个答案对于海报来说可能为时已晚,但由于这个问题帮助我解决了我的问题,我认为在这里发布解决方案是好的!