DEV Community

Haris
Haris

Posted on

Task Based Programming Over Thread Base

Prefer Task based Programming to Thread-Based

If you want to run something Async you have two basic choices: std::thread and std::async

int doAsyncWork();

std::thread th(doAsyncWork);
Enter fullscreen mode Exit fullscreen mode
// Better to use Async

auto future = std::async(doAsyncWork);
Enter fullscreen mode Exit fullscreen mode

std::async(doAsyncWork) is considered a task. The task is superior because it returns a future value which we can use to sync up our program. Async task also has a get function which we can use to get the status and or if our work function emits an exception.

Async task also provides more abstraction.

What is the meaning of Thread?

  • Hardware threads, perform computation. Contemporary machine architectures offer one or more hardware threads per CPU core.
  • Software threads (also known as OS threads or system threads) are the threads that the operating system manages across all processes and schedules for execution on hardware threads.
  • std::threads are objects in a C++ process that act as handles to underlying software threads.

Software threads are a limited resource. If you try to create more than the system can provide, a std::system_error exception is thrown. (This is even true for a function that is marked no-except)

Even if you don’t run out of threads, you can have trouble with oversubscription. That’s when there are more ready-to-run, thread scheduler time-slices the software threads on the hardware. Such context switches increase the overhead.

Your life would be much easier if you dump all this management to someone else and that someone else is std::async

Task doesn’t have same problem as Threads.

Well Task would almost never have this out of threads problem because Async task doesn’t guarantee that it will create a new software thread. Rather it permits the scheduler to arrange for the function to be run on thread requesting the doAsyncWork() result.

Launch Policy

async sometimes run on the same thread that is expecting its output, well that is only true if you use the default launch policy which is a combination of both async and deferred.
The behavior depends on the launch policy:

  • std::launch::async → The function is guaranteed to run on a new thread.
  • std::launch::deferred → The function does not run immediately. Instead, it runs only when you call future.get() or future.wait(), and it runs on the same thread that calls get or wait.
  • Default (std::launch::async | std::launch::deferred) → The implementation decides whether to run it asynchronously (new thread) or deferred (same thread, lazy execution).

Top comments (0)