4

Poco::HTTPServerの使用で問題が発生しています。TCPServerのドキュメントに記載されているように:

stop()を呼び出した後、新しい接続は受け入れられず、キューに入れられたすべての接続が破棄されます。ただし、すでに提供されている接続は引き続き提供されます。

すべての接続は独自のスレッドで実行されます。デストラクタは正常に接続と呼ばれているように見えますが、スレッドはまだ存在し、接続を提供しているため、セグメンテーション違反が発生します。

すべての接続をキャンセルしたい。したがってPoco::ThreadPool::defaultPool().stopAll();、サーバークラスのデストラクタで使用します。これにより、ThreadPoolのドキュメントにも記載されている動作が発生します(10秒かかり、オブジェクトは削除されません)。

スレッドが10秒以内に停止しなかった場合(たとえば、プログラミングエラーのため)、基になるスレッドオブジェクトは削除されず、このメソッドはとにかく戻ります。これにより、スレッドの動作が正しくない場合に、多かれ少なかれ正常にシャットダウンできます。

私の質問は:どうすればもっと優雅な方法を達成できますか?Pocoライブラリ内のプログラミングエラーはありますか?

編集:IDEとしてEclipse+cdtを備えたGNU/Linux(Ubuntu 10.04)を使用しています。ターゲットシステムは組み込み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(); }
}
4

2 に答える 2

6

これは実際にはstopAll()メソッドの実装におけるバグです。現在アクティブな接続を閉じた後、リスニングソケットがシャットダウンされます。これにより、サーバーはその間の新しい接続を受け入れることができます。新しい接続は閉じられず、実行を継続します。回避策は、HTTPServer :: stop()を呼び出してから、HTTPServer :: stopAll()を呼び出すことです。提案された修正を含む上流のバグを報告しました:

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

于 2014-05-02T12:21:12.550 に答える
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
    }
};

この回答はポスターには遅すぎるかもしれませんが、質問は私の問題を解決するのに役立ったので、ここに解決策を投稿するのは良いことだと思います!

于 2013-06-04T13:30:15.267 に答える