调用stop()和析构函数后仍然提供Poco HTTPServer连接

时间:2011-06-14 08:08:46

标签: c++ linux multithreading poco-libraries

我在使用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(); }
}

2 个答案:

答案 0 :(得分:6)

这实际上是stopAll()方法实现中的一个错误。关闭当前活动连接后,侦听套接字正在关闭,这允许服务器接受其间的新连接,而这些连接又不会关闭并继续运行。解决方法是调用HTTPServer :: stop(),然后调用HTTPServer :: stopAll()。我报告了上游的错误,包括一个建议的修复:

https://github.com/pocoproject/poco/issues/436

答案 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
    }
};

这个答案对于海报来说可能为时已晚,但由于这个问题帮助我解决了我的问题,我认为在这里发布解决方案是好的!