2012-11-07 71 views
10

的,我需要做這樣的事情往往比更多的元件組合:如何使用的std ::綁定的std :: shared_ptr的

AsyncOperation * pAsyncOperation = new AsyncOperation(); 
auto bindOperation = std::bind(&AsyncOperation::operator(), std::ref(*pAsyncOperation)); 
std::thread thread(bindOperation); 
thread.join(); 

AsyncOperation是任何自定義類實現operator()(又稱仿或功能對象)

是否可以指示std::bind使用std::shared_ptr而不是std::ref? 這可以防止內存泄漏,而不需要在pAsyncOperation上保留引用,並且會在線程結束時自動刪除AsyncOperation,即該異步任務的結束。

編輯:我不總是有權訪問std :: thread,線程庫可以是boost :: thread甚至任何其他平臺相關的線程。結果,不能訪問std :: async。

我的主要問題是在std :: bind中擁有一個佔有的概念。

+0

您是否嘗試過使用'的std :: shared_ptr'?看起來編譯沒有問題:http://liveworkspace.org/code/1e83d9698703711b7ed2ce0d44cf86f2 – PiotrNycz

+1

你需要知道的是,'std :: bind'按值存儲綁定參數(即,如傳遞),因此,如果你通過擁有指針通過值作爲參數之一,該指針被「複製」到所產生的仿函數中,因此,即使在原始的「shared_ptr」超出範圍之後仍保留所有權。 – haelix

回答

10

這工作:

struct AsyncOperation { 
    void operator()() 
    { 
     std::cout << "AsyncOperation" << '\n'; 
    } 
}; 

int main() { 
    std::shared_ptr<AsyncOperation> pAsyncOperation = std::make_shared<AsyncOperation>(); 
    auto bindOperation = std::bind(&AsyncOperation::operator(), pAsyncOperation); 
    std::thread thread(bindOperation); 
    thread.join(); 
} 

參見:http://liveworkspace.org/code/4bc81bb6c31ba7b2bdeb79ea0e02bb89

+0

你需要使用'make_shared',還是將'std :: shared_ptr pAsyncOperation(new AsyncOperation());'do? – akaltar

+1

@akaltar你可以使用「樣式」 - 但make_shared更好 - 閱讀:https://stackoverflow.com/questions/31232146/why-is-it-better-to-use-stdmake-instead-of-the-構造函數 – PiotrNycz

7

你需要動態分配AsyncOperation嗎?如果沒有,我會這麼做:

auto f = std::async([]{ AsyncOperation()(); }); 
f.wait(); 

否則:

std::unique_ptr<AsyncOperation> op(new AsyncOperation); 
auto f = std::async([&]{ (*op)(); }); 
f.wait(); 

當然你也可以使用std::thread,但它可以提供更多的問題(在其他線程,即異常處理)。 std::bind也有自己的問題,你可能會更好地結束一個lambda。

如果你真的需要傳遞的所有權轉讓給其他線程你也可以這樣做:

std::unique_ptr<AsyncOperation> op(new AsyncOperation); 
auto f = std::async([&](std::unique_ptr<AsyncOperation> op){ (*op)(); }, std::move(op)); 
f.wait(); 

爲lambda表達式不支持移動型捕捉呢。

我希望有幫助。

相關問題