2012-01-21 2 views
0

Я хотел бы реализовать метод, как это:emulate std :: async с std :: launch :: sync?

boost::unique_future<int> foo() 
{ 
    return defer([=] // call this lambda on boost::unique_future<int>::get(); 
    { 
     return prime(10); 
    }); 
} 

я знаю boost::promise и boost::packaged_task и set_wait_callback, однако, поскольку возвращаемый будущее принимает ссылку либо это не будет работать?

Я знаю, что есть std::async и std::launch::sync, но как можно эмулировать его с помощью boost и vs2010?

std::unique_future<int> foo() 
{ 
    return std::async(std::launch::sync, [=] 
    { 
     return prime(10); 
    }); 
} 

ответ

2

Вы можете использовать set_wait_callback, вы просто должны динамически выделять обещание, и удалить его в функцию обратного вызова после того, как вы установите значение:

#include <boost/thread.hpp> 
#include <iostream> 

void callback(boost::promise<int>&p) { 
    std::cout<<"callback"<<std::endl; 
    p.set_value(42); 
    delete &p; 
} 

boost::unique_future<int> f() 
{ 
    boost::promise<int> *p=new boost::promise<int>; 
    p->set_wait_callback(callback); 
    return p->get_future(); 
} 

int main() 
{ 
    boost::unique_future<int> uf(f()); 
    std::cout<<"main()"<<std::endl; 
    int val=uf.get(); 
    std::cout<<"val="<<val<<std::endl; 
} 
+0

Одна проблема мэра. Если get() не вызывается, то обещание просачивается. – ronag

+0

Если вы используете shared_ptr , тогда вы получите круговую зависимость, и она все равно будет течь. – ronag

+0

Вы правы. Лучшим решением было бы изменить код повышения, чтобы делать то, что вы хотите. –

0

Вы можете использовать код этого билета: https://svn.boost.org/trac/boost/ticket/4710

+0

Хотя это просто выполнит задачу сразу же в другом потоке, я хочу, чтобы она выполнялась только на 'get'. – ronag

Смежные вопросы