Skip to content

Store tasks with explicit control for execution – std::packaged_task

Example

Asssume you have one or more time consuming calculations finally providing some result:

class CalculateSomething1
{
public:
    CalculateSomething(int in_val);
    SomeResult1 operator()() {return ...}
};
class CalculateSomething2
{
    ...
};

Then you can store the execution within a task:

#include <future>
{
    // Create function objects
    CalculateSomething1 calc1(17);
    CalculateSomething2 calc2(42);
    
    // Define the tasks
    std::packaged_task<SomeResult1()> calcTask1(calc1);
    std::packaged_task<SomeResult2()> calcTask2(calc2);
    // Get the futures for later requesting results
    std::future<SomeResult1> calcResult1 = calcTask1.get_future();
    std::future<SomeResult2> calcResult2 = calcTask2.get_future();

    // Calculate result

    // Attention: Works but synchronously executes 
    // the calculation in the calling thread!
    // calcTask1();
    // calcTask2();

    // Better choose your own threads for execution
    std::thread thread1 (std::move(calcTask1));
    thread1.detach();
    std::thread thread2 (std::move(calcTask2));
    thread2.detach();

    // Wait for end of calculation and get the results 
    SomeResult1 result1 = calcResult1.get();
    SomeResult2 result2 = calcResult2.get();
}

Remarks

Several packaged_tasks may be stored within a container and client code can use a set of available worker threads to process all container entries.

std::packaged_task – most used features

MethodDescription
get_futurereturns the future for later accessing the promised result
operator()executes the function which is stored within the packaged task. The function is executed in the calling thread! The client code is responsible for using a separate thread.

For more info see std::packaged_task – complete reference at CppReference.com