2013-04-30 22 views
19

Il async richiamo sottostante blocca perché il distruttore del futuro restituita sta bloccando:Soluzione alternativa per il blocco di async?

void foo() {} 

void foo_async() { 
    std::async(std::launch::async, foo); 
} 

Ma io non voglio bloccare!

che sto valutando la possibilità di utilizzare la seguente soluzione:

void foo_async() { 
    std::thread(foo).detach(); 
} 

È questo ok? O consiglieresti una soluzione diversa?

+3

Se non è necessario restituire un valore dall'attività o attendere che finisca, mi sembra ragionevole. – jcoder

risposta

10

È possibile utilizzare la seguente versione di async che fornisce un futuro non bloccante. In quanto tale, puoi trarre vantaggio dal futuro se ne hai bisogno e dall'altra parte puoi semplicemente ignorarlo quando vuoi un compito ignifugo.

template< class Function, class... Args> 
std::future<typename std::result_of<Function(Args...)>::type> async(Function&& f, Args&&... args) 
{ 
    typedef typename std::result_of<Function(Args...)>::type R; 
    auto bound_task = std::bind(std::forward<Function>(f), std::forward<Args>(args)...); 
    std::packaged_task<R()> task(std::move(bound_task)); 
    auto ret = task.get_future(); 
    std::thread t(std::move(task)); 
    t.detach(); 
    return ret; 
} 
+0

Puoi spiegare perché questo non è bloccante? Per me, sembra che bloccherebbe ancora dall'altra parte una volta chiamato il futuro distruttore. – thejinx0r

+0

@ thejinx0r futuro distruttore dall'attività in pacchetto non blocca – inf

4

Se si desidera davvero ignorare la chiamata a foo(), direi che la soluzione alternativa è OK.

Altrimenti, basta fare auto f = std::async(std::launch::async, foo);, e possibilmente restituire il futuro da foo_async().

+1

Se un'eccezione fuoriesce da 'foo', boom. –

Problemi correlati