2010-05-28 71 views
3

我的應用程序問題如下 -Boost shared_ptr use_count函數

我有一個大的結構foo。由於這些數據量很大,並且出於內存管理的原因,我們不希望在數據處理完成時將其刪除。

我們將它們存儲在std::vector<boost::shared_ptr<foo>>.

我的問題是有關知道什麼時候所有的處理完成。第一個決定是我們不希望任何其他應用程序代碼在結構中標記完整的標誌,因爲程序中有多個執行路徑,我們無法預測哪一個是最後一個。

所以在我們的實現中,一旦處理完畢,我們刪除的boost::shared_ptr<foo>>所有副本除了一個向量中。這會將shared_ptr中的引用計數器放到1.是否可以使用shared_ptr.use_count()來查看它是否等於1,以知道應用程序的所有其他部分何時完成數據。

一個額外的原因,我問的問題是,在共享指針shared_ptr升壓文檔建議不使用「use_count」爲產品代碼。


編輯 - 我沒有說的是,當我們需要一個新的富,我們將掃描foo的指針尋找一個foo的載體,其是當前未使用和使用FOO下一輪的處理。這就是爲什麼我認爲使用1的引用計數器是確保這個特定foo對象不再被使用的安全方法。

+0

你的代碼是多線程的嗎?如果是的話,這將改變答案。 – wheaties 2010-05-28 14:01:01

+0

是的,有3到6個線程處理數據 – 2010-05-28 14:09:28

回答

4

我的直接反應(我得承認,它沒有比這更)是,它聽起來就像你想獲得某種形式的池分配器的效果。你可能會更好地超載operator newoperator delete以更直接地獲得你想要的效果。有了這樣的事情,你可以像平常一樣使用shared_ptr,而你想延遲的其他工作,將在該類的operator delete中處理。

這留下了一個更基本的問題:你真的想用這個完成什麼?從內存管理的角度來看,一個共同的願望是一次爲大量對象分配內存,在整個塊爲空之後,立即釋放整個塊。如果您正在嘗試按照該順序進行操作,那麼通過超載newdelete比通過玩shared_ptruse_count來實現幾乎肯定更容易。

編輯:根據您的評論,超載newdelete類聽起來像是正確的事情。如果有的話,集成到您現有的代碼可能會更容易;事實上,你通常可以完全透明地做到這一點。

分配器的一般想法與您在編輯的問題中概述的幾乎相同:有一個結構(位圖和鏈表都是常見的)來跟蹤您的自由對象。當new需要分配一個對象時,它可以掃描位向量或查看自由對象鏈表的頭部並返回其地址。

這是鏈接列表可以很好地工作的一種情況 - 您(通常)不必擔心內存使用情況,因爲您將鏈接存儲在空閒對象中,並且(幾乎)不會有走這個列表,因爲當你需要分配一個對象時,你只需要抓取列表中的第一個項目。

這類事情在小物件中特別常見,因此您可能要查看關於其小對象分配器的章節(以及自Andrei Alexandrescu關於他的新概念之後的一兩篇文章如何做這種事情)。還有Boost :: pool分配器,它通常至少有點類似。

+0

您已經總結了我的問題。我們試圖將它作爲我們可以從中獲得下一個免費的對象的對象池。 無論我們做什麼,我們也必須看看我們是否也可以將其改裝到我們現有的代碼庫以及我們的新應用程序。 – 2010-05-28 14:08:24

0

我建議,而不是試圖使用的shared_ptr的use_count跟蹤,它可能是更好地實現自己的使用計數器。這樣你就可以完全控制這個,而不是使用shared_ptr的那個,正如你所說的那樣,不建議這樣做。您還可以預先設置自己的計數器,以允許您知道需要對數據執行操作的線程數量,而不是依賴它們在開始時初始化以獲取其結構副本。

3

如果你想知道該使用次數是否爲1,使用unique()成員函數。

2

我會說你的應用程序應該有一定的消除從應用程序的其他部分爲富所有引用的方法,並且該方法應該用來代替檢查use_count()。另外,如果use_count()大於1,你的程序會做什麼?您不應該依賴shared_ptr的功能來消除所有引用,您的應用程序體系結構應該能夠消除引用。作爲從矢量中刪除它之前的最終檢查,您可以通過assert(unique())來驗證它是否真的被釋放。

2

我認爲您可以使用shared_ptr的自定義刪除功能在最後一個副本發佈時調用特定功能。那樣,你根本就沒有使用use_count

您需要在您的vector中保存除shared_ptr副本以外的內容,以便shared_ptr僅跟蹤未完成的處理。

Boost在shared_ptr文檔中有several examples of custom deleters

相關問題