2012-12-08 165 views
1

我想實現一種機制,允許我阻止程序流程,直到異步操作完成。 (主要是在單元測試中不存在消息循環中使用。)等待異步操作

我的代碼創建一個線程和等待線程內部的狀況通知:

#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