非同步操作時的內存管理?
請教大家一個問題:
比如說我有一個A類,其中A類的post方法是一個非同步的操作
class A
{
public:
template &
void post(Handler handle) {
// async...
}
};
我要在foo的test中調用a對象的post方法,當post的業務處理完成後會通知xxx回調。
現在問題就來了,foo類的test函數也是頻繁調用的,也就是說post非同步函數還未執行完,又會產生一次test的調用,造成a對象被reset,這樣就錯誤。後來,我又想不用智能指針,直接在test函數中進行這樣的設計
class foo
{
public:
void test() {
a.reset(new A());
a.post(xx);
}
void xx()
{
}
private:
boost::shared_ptr& a;
};
但是這樣怎樣去進行內存管理呢?採用狀態機?補充:post方法是一個非同步的,但是post方法裡面可能也會調用一些非同步的方法,總之最後會通知xx函數。
void test() {
A* a = new A();
a.post(XX);
}
樓主的需求表達不太明確,你應該告訴知友你要解決的問題是什麼,而不是如何改你現在寫的代碼。我只能按我從樓主的問題中讀到的,約定最終所有任務完成之後一定會調用`xx`函數,所以可以給`xx`做文章:
void test() {
A* a = new A();
a-&>post([=] () {
try {
XX(); // Call XX callback
} catch (...) {
// Do nothing...
}
delete a;
});
}
不知道樓主所要求的`xx`函數參數列表有什麼要求,我這裡假設的是空。
另外,我也假設是在`xx`函數被調用之後,不會再調用同一個A的成員函數。正確的方法是這樣子的:
auto b = this-&>a;
a-&>post([b]()
{
// 你的代碼,譬如說調用xx
});
確保了post的回調結束之前,b都還在,不管你a怎麼reset都沒關係。
你需要boost::enable_shared_from_this和boost::bind,讓A類自己管理自己就好了我就假設你用的asio吧,因為不清楚該怎麼修改你的代碼好,asio的example裡面就有很好的示例:Daytime.3 - An asynchronous TCP daytime server簡單來說就是通過bind生成一個閉包來持有tcp_connection這個類的智能指針,這樣智能指針的引用計數就一直不會減少到0,也就不會釋放這個對象。在tcp_connection類內部就用shared_from_this()來獲取指針。只要還繼續發起非同步操作,就是中會有一個閉包持有這個智能指針,直到不在繼續發起非同步操作,就可以讓這個connection類自生自滅了。
可以在構造函數里new析構函數里delete,這代表每個foo對應一個A可以用vector或list之類的把所有new出來的A保存起來,合適的時候delete,這代表一個foo對應多個A可以在每次new之前先delete之前的A,這代表每個foo對應一個不定的A由需求決定
這個不是很簡單嗎?改一下post()的回調函數,讓它回傳A的實例,把void xx()改成void xx(A* a),把a回傳給xx()去析構,根本用不著智能指針呀。如果不能改post(),可以用functor包裝一下。
手機答題。
以你的第二個方案為基礎。xx方法增加一個A *參數。回調xx時把a的指針傳回來,在xx方法中delete。這個方法可行,不過感覺不是很優雅。--Update-------------------------------
剛剛測試了一下,C++成員函數內部可以用delete this完成析構,釋放對象佔用的內存(查看彙編證實)。題主可以試著利用這一點。BTW:看彙編時發現delete this對應的指令裡面有對this是否為NULL的檢查。請問 @vczh 這是C++標準還是g++ (Debian 4.4.5-8) 4.4.5的特性?我一般用shared_ptr處理
推薦閱讀:
※是否有可能發現一段內存被野指針修改了?
※如何設計內存池?
※為什麼調用 std::map::clear() 後內存佔用率沒有降低?
※最近電腦每次開機內存佔用與上次關機時差不多,只有重啟後內存才會降到20左右,這是怎麼回事啊?
※電腦內存突然佔用過多是為什麼?