2012-11-07 4 views
10

의 사용을 결합하는 방법 : AsyncOperation나는이 더 자주보다 같은 것을 할 필요가 표준과 표준 : : 바인드 :: shared_ptr의

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

도 펑로 알려진 operator()를 구현하는 사용자 정의 클래스 (인을 또는 함수 개체).

std::bindstd::ref 대신 std::shared_ptr을 사용할 수 있습니까? 이렇게하면 pAsyncOperation에 대한 참조를 유지할 필요없이 메모리 누수가 방지되고 스레드의 끝에 자동으로 AsyncOperation이 삭제되므로 비동기 작업이 종료됩니다.

편집 : 나는 항상 std :: thread에 액세스 할 수있는 것은 아니지만 스레드 라이브러리는 boost :: thread 또는 다른 플랫폼 종속 스레드 일 수 있습니다. 결과적으로 std :: async에 액세스 할 수 없습니다.

내 주요 문제는 std :: bind에 소유 개념을 갖는 것입니다.

+0

당신이'표준 : 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::thread을 사용할 수 있습니다

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

, 그러나 그것은 더 많은 문제 (다른 스레드 즉, 예외 처리)를 제공 할 수 있습니다. std::bind도 자체적 인 문제가 있으며 아마도 람다로 끝나는 것이 좋습니다. 당신이 정말로 다른 스레드에 대한 소유권을 통과해야하는 경우

당신은 또한 그 작업을 수행 할 수 있습니다 이동 유형을 지원하지 않습니다 람다 아직 캡처

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

한다.

도움이 되었기를 바랍니다.