2011-06-14 67 views
4

我正面臨使用Poco :: HTTPServer的問題。作爲TCPSERVER的DOC descibed:Poco HTTPServer連接在調用stop()和析構函數後仍然提供服務

)呼籲停止(後,沒有新的連接將被接受,所有 排隊的連接將被丟棄。然而,已經提供服務的連接, 將繼續提供服務。

每個連接都在其自己的線程中執行。 雖然看起來析構函數被成功調用,但連接線程仍然存在,併爲連接提供服務,從而導致分段錯誤。

我想取消所有連接。因此,我在我的服務器類,這導致線程池的文檔還描述的行爲的析構函數使用Poco::ThreadPool::defaultPool().stopAll();(這需要10秒和對象不會被刪除):

如果一個線程都無法阻止在10秒內(例如由於編程 錯誤),底層線程對象將不會被刪除 並且此方法將返回。這允許或多或少的 在行爲不當的情況下正常關機。

我的問題是:我如何完成更優雅的方式? Poco庫中的編程錯誤?編輯:我使用GNU/Linux(Ubuntu 10.04)與eclipse + cdt作爲IDE,目標系統是嵌入式Linux(內核2.6.9)。在兩個系統上,我都經歷了所描述的行爲

我正在處理的應用程序應通過網絡界面進行配置。所以服務器發送一個事件(上傳新配置)到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

的POCO標籤:指普通老式CLR對象,一個簡單的對象不遵循任何對象模型,公約或框架。不知怎的,我不認爲你的意思 – Tim 2011-06-14 09:55:56

+0

@Tim你說得對,謝謝。 – Michael 2011-06-14 10:02:41

+2

有人可以爲repo堆創建Poco C++庫的標籤http://pocoproject.org/ – Tim 2011-06-14 10:08:30

回答

6

這實際上是一個執行stopAll()方法的錯誤。監聽套接字在關閉當前活動連接後被關閉,這允許服務器接受兩者之間的新連接,而這些連接又不會關閉並繼續運行。解決方法是調用HTTPServer :: stop(),然後調用HTTPServer :: stopAll()。我報告的錯誤的上游包括建議修復:

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

0

您應該避免使用Poco::ThreadPool::defaultPool().stopAll();,因爲它沒有提供可以控制哪個線程停止。

我建議你創建一個專門爲你的Poco:HTTPServer實例的Poco::ThreadPool,並在服務器停止時停止該池的線程。

有了這個,你的代碼應該是這樣的:

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

這個答案可能是太晚了海報,但因爲這個問題幫我解決我的問題,我認爲這是很好的發佈在這裏解決!

+0

感謝您的回答,這對項目來說已經太晚了,但對我來說不是這樣,歡呼聲 – Michael 2013-06-17 19:07:38

+0

現在我又看到了問題,我看到Poco :: HTTPServer現在有一個方法stopAll(),它可能會取消所有當前的連接。我不認爲它在2011年... – Michael 2013-06-17 19:25:04

+1

'Poco :: HTTPServer :: stopAll()'單獨使用並不能解決問題。如果我使用'stop'然後'stopAll',我的測試通過......但是在閱讀代碼後,我看到'stopAll'只不過是向連接線程發送一個事件(固有地是異步的),然後調用'stop'。因此,我對使用'stopAll'不是很有信心。無論如何,感謝兩年後接受我的回答! – 2013-06-18 07:09:44

相關問題