Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use std::async without waiting for the future limitation?

High level
I want to call some functions with no return value in a async mode without waiting for them to finish. If I use std::async the future object doesn't destruct until the task is over, this make the call not sync in my case.

Example

void sendMail(const std::string& address, const std::string& message) {     //sending the e-mail which takes some time... }  myResonseType processRequest(args...) {     //Do some processing and valuate the address and the message...      //Sending the e-mail async     auto f = std::async(std::launch::async, sendMail, address, message);      //returning the response ASAP to the client     return myResponseType;  } //<-- I'm stuck here until the async call finish to allow f to be destructed.   // gaining no benefit from the async call. 

My questions are

  1. Is there a way to overcome this limitation?
  2. if (1) is no, should I implement once a thread that will take those "zombie" futures and wait on them?
  3. Is (1) and (2) are no, is there any other option then just build my own thread pool?

note:
I rather not using the option of thread+detach (suggested by @galop1n) since creating a new thread have an overhead I wish to avoid. While using std::async (at least on MSVC) is using an inner thread pool.

Thanks.

like image 319
Roee Gavirel Avatar asked Feb 03 '14 15:02

Roee Gavirel


People also ask

Should I use std async?

So if you want to make sure that the work is done asynchronously, use std::launch::async . @user2485710 it needs to block when you retrieve the result, if you need the result in the launching thread. It cannot use the result if the result is not ready. So if you go to get the result, you have to wait until it is ready.

Does STD async use thread pool?

For now, we know that if no policy is specified, then std::async launches a callable function in a separate thread. However, the C++ standard does not specify whether the thread is a new one or reused from a thread pool. Let us see how each of the three implementations launches a callable function.

What is std :: async?

The function template async runs the function f asynchronously (potentially in a separate thread which might be a part of a thread pool) and returns a std::future that will eventually hold the result of that function call. 1) Behaves as if (2) is called with policy being std::launch::async | std::launch::deferred.

Is std :: future thread safe?

std::shared_futureAccess to the same shared state from multiple threads is safe if each thread does it through its own copy of a shared_future object.


1 Answers

You can move the future into a global object, so when the local future's destructor runs it doesn't have to wait for the asynchronous thread to complete.

std::vector<std::future<void>> pending_futures;  myResonseType processRequest(args...) {     //Do some processing and valuate the address and the message...      //Sending the e-mail async     auto f = std::async(std::launch::async, sendMail, address, message);      // transfer the future's shared state to a longer-lived future     pending_futures.push_back(std::move(f));      //returning the response ASAP to the client     return myResponseType;  } 

N.B. This is not safe if the asynchronous thread refers to any local variables in the processRequest function.

While using std::async (at least on MSVC) is using an inner thread pool.

That's actually non-conforming, the standard explicitly says tasks run with std::launch::async must run as if in a new thread, so any thread-local variables must not persist from one task to another. It doesn't usually matter though.

like image 82
Jonathan Wakely Avatar answered Oct 07 '22 23:10

Jonathan Wakely