2012-12-08 11 views
1

비동기 작업이 완료 될 때까지 프로그램 흐름을 차단할 수있는 메커니즘을 구현하고 싶습니다. (아무런 메시지 루프가없는 곳 구름 유닛 테스트에 사용된다.)비동기 작업 대기

I 가진 코드는 스레드를 생성하고 스레드 내부 상태 통지를 기다린다 :

#include <chrono> 
#include <condition_variable> 
#include <iostream> 
#include <memory> 
#include <mutex> 
#include <stdexcept> 
#include <thread> 

struct Blocker { 
    Blocker() : 
     wait_thread([this]() { 
      std::mutex mtx; 
      std::unique_lock<std::mutex> lck(mtx);    
      cond.wait(lck); 
     }) 
    { 
    } 

    void wait() { wait_thread.join(); } 

    void notify() { cond.notify_one(); } 

    std::condition_variable cond;  
    std::thread wait_thread; 
}; 

template<typename Callback> 
void async_operation(const Callback & cb) { cb(); } 

int main() { 
    Blocker b; 
    async_operation([&](){ b.notify(); }); 
    b.wait(); 
} 

문제는 그 종종 스레드가 시작되기 전에 notify에 대한 호출이 발생하기 때문에 교착 상태가 발생합니다. 이 문제를 어떻게 해결해야합니까?

+0

조건 변수는 Windows 이벤트 개체가 아닙니다. – chill

+1

['std :: async'] (http://en.cppreference.com/w/cpp/thread/async)를 알고 있습니까? 이게 도움이되는지 모르겠지만, 그래야만하는 것처럼 들립니다.) – leemes

답변

2
#include <mutex> 
#include <condition_variable> 

struct blocker 
{ 
    blocker() : done (false) {} 

    void 
    notify() 
    { 
    std::unique_lock<std::mutex> lock (m); 
    done = true; 
    c.notify_all(); 
    } 

    void 
    wait() 
    { 
    std::unique_lock<std::mutex> lock (m); 
    while (!done) 
     c.wait (lock); 
    } 

    bool done; 
    std::mutex m; 
    std::condition_variable c; 
}; 
+0

분명히 이것은 '완료'에 UB 데이터 경주를 도입합니다. 이는 원자가 아닙니다. – Puppy

+0

확실히 잠금 상태에서만 액세스됩니다. – chill

+0

아아, 왜 나 자신을 생각할 수 없었다 ..? 어쨌든 감사합니다! – StackedCrooked