2012-01-16 28 views
9

Doğrudan boost::thread ve boost::bind'u kullanmadan, aşağıdaki kodun eşdeğerini uygulamanın bir yolu var mı?Destek eşdeğeri std :: async()

std::string func() 
{ 
    std::string str("Hello from async task!"); 
    return str; 
} 

int main() 
{ 
    auto ftr = std::async(&func); 
    std::cout << "Hello from main!"; 
    std::string str = ftr.get(); 
    std::cout << str << std::endl;  
    return 0; 
} 

Bu bölüm özellikle: auto ftr = std::async(&func);?

cevap

8

Kesinlikle. async<T>(std::function<T()>)'u, func()'u ilk bekledikleri an başlatan bir geleceği geri döndürün. Eşzamanlılık almayacaksınız, ancak API aslında işlevin senkronize olmayan bir şekilde çalışacağını garanti etmiyor, bu yüzden sorun değil.

İşletim sistemine özel bir iş parçacığı kitaplığına erişiminiz varsa, elbette bunu da kullanabilirsiniz. Bununla birlikte, saklanan istisnaların taşınabilir şekilde uygulanamayacağını unutmayın; Bir polimorfik klon işlevi olanlara desteklenen istisnaları kısıtlayamazsanız, C++ uygulamasından ek destek gerektirir. Daha fazla bilgi için bkz. this question. Detaylı cevap için

// NOTE - we assume a SINGLE THREADED environment 

template<typename T> 
class myfuture_detail { 
    mutable boost::variant<T, boost::function<T()> > val; 

public: 
    myfuture_detail(const boost::function<T()> &f) 
     : val(f) { } 

    const T &get() const { 
     if (T *t = boost::get<T>(&val)) { 
      return *t; 
     } else { 
      boost::function<T()> f = *boost::get<boost::function<T> >(&val); 
      val = f(); 

      T *t = boost::get<T>(&val); 
      assert(t); 

      return *t; 
     } 
    } 
}; 

template<typename T> 
class myfuture { 
    boost::shared_ptr<myfuture_detail<T> > ptr; 

public: 
    myfuture(const boost::function<T()> &f) 
     : ptr(boost::make_shared<myfuture_detail<T> >(f)) 
    {} 

    myfuture() { } 

    const T &get() const { 
     return ptr->get(); 
    } 
}; 
+0

Teşekkür:

son uygulama böyle bir bitin (denenmemiş) görünebilir! Ben meta programlama açısından acemi bir şeyim, bu yüzden OP'deki örnekle aynı şekilde nasıl kullanılabileceğinden emin değilim ... Örneğin, std :: async () 'içine gelmek? 'Myfuture' sınıfının bir şekilde bir "boost :: thread" öğesine bağlı olması gerekir mi? –

+1

Bu aslında asenkron değildir. std :: async'ın sözleşmesi, async rutininin asenkron olarak çalıştırılacağını garanti etmez. ".get()" işlevine ulaşana kadar zaman uyumsuz iş parçacığının hiçbir zaman zamanlanmayacağını düşünün. Etkin bir şekilde senkronize edilir. Burada yaptığım şey budur - çünkü hiçbir iş parçacığınız olmadığı için, sadece eşzamansız bir şekilde çalışıyormuş gibi davranıyordum ve sadece sonuç aramaya gelene kadar hiçbir şey yapılmadığı anlaşılıyor. – bdonlan

+0

"* Bununla birlikte, kayıt dışı durumların taşınabilir şekilde uygulanamayacağını unutmayın." [Boost.Exception] (http://www.boost.org/libs/exception/) bunu yapmıyor mu? – ildjarn