使用boost :: asio我使用async_accept來接受連接。這很好,但有一個問題,我需要一個建議如何處理它。利用典型async_accept:boost :: asio acceptor避免內存泄漏
Listener::Listener(int port)
: acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), port))
, socket(io) {
start_accept();
}
void Listener::start_accept() {
Request *r = new Request(io);
acceptor.async_accept(r->socket(),
boost::bind(&Listener::handle_accept, this, r, placeholders::error));
}
工作正常,但有一個問題:請求對象與普通新因此它可以內存「泄漏」創建。不是真的泄漏,它只在程序停止時泄漏,但是我想讓012g幸福。
確定有一個選項:我可以將其替換爲shared_ptr,並將其傳遞給每個事件處理程序。這將工作,直到程序停止,當asio io_service正在停止,所有對象將被銷燬,請求將被free'd。但這樣我總是必須有一個活躍的asio事件請求,否則它將被銷燬!我認爲它的直接方式崩潰,所以我不喜歡這個變種。
UPD第三種變體:Listener
將shared_ptr列表保存到活動連接。看起來不錯,我更喜歡使用這個,除非找到更好的方法。缺點是:由於這個模式允許在空閒連接上進行「垃圾收集」,因此它不安全:從Listener中刪除連接指針將立即銷燬它,當某個連接的處理程序在其他線程中處於活動狀態時,會導致segfault。在這種情況下,使用互斥鎖無法解決這個問題,我們必須鎖定幾乎任何東西。
有沒有辦法使acceptor工作與連接管理一些美麗和安全的方式?我會很高興聽到任何建議。
這不是你的'Listener'類的設計問題,或者你的策略是用指針而不是函數對象來使用'bind',而不是'acceptor'類的問題? – Hurkyl
它不是一個函數對象=)但無論如何,我沒有看到如何純函數可以解決這個問題。 – PSIAlt
@PSIAlt請你詳細說明爲什麼習慣'shared_ptr' /'enable_shared_from_this'方法不起作用?我不明白* active * asio事件的上下文。另外,如果'Request'沒有創建它自己的異步調用鏈,並且將它的生命週期綁定到鏈上,那麼其他對象是否維護'Request'對象的句柄? –