Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9113569
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T03:59:46+00:00 2026-06-17T03:59:46+00:00

I am trying to establish some heuristics to help me decide the appropriate std::thread

  • 0

I am trying to establish some heuristics to help me decide the appropriate std::thread class to use.

As I understand it, from highest level (simplest to use, but least flexible) to lowest level, we have:

  1. std::async with/std::future (std::shared_future) (when you want to execute on a one-time throw-away producer-thread async)
  2. std::packaged_task (when you want to assign a producer, but defer the call to the thread)
  3. std::promise (???)

I think I have a decent grasp of when to use the first two, but am still unclear about std::promise.

std::future in conjunction with a std::async call, effectively transforms a producing callback/functor/lambda to an asynchronous call (which returns immediately, by definition). A singular consumer can call std::future::get(), a blocking call, to get its results back.

std::shared_future is just a version which allows for multiple consumers.

If you want to bind a std::future value with a producer callback, but want to defer the actual invocation to a later time (when you associate the task to a spawning thread), std::packaged_task is the right choice. But now, since the corresponding std::future to the std::package_task could, in the general case, be accessed by multiple-threads, we may have to take care to use a std::mutex. Note that with std::async, in the first case, we don’t have to worry about locking.

Having read some interesting links on promise, I think I understand its mechanisms and how to set them up, but my question is, when would you choose to use a promise over the other three?

I’m looking more for an application-level answer, like a rule-of-thumb (fill the ??? in 3. above), as opposed to the answer in the link (eg use std::promise to implement some library mechanism), so I can more easily explain how to choose the proper class to a beginning user of std::thread.

In other words, it would be nice to have an useful example of what I can do with a std::promise that cannot be done with the other mechanisms.

ANSWER

A std::future is a strange beast: in general, you cannot modify its value directly.

Three producers which can modify its value are:

  1. std::async through an asynchronous callback, which will return a std::future instance.
  2. std::packaged_task, which, when passed to a thread, will invoke its callback thereby updating the std::future instance associated with that std::packaged_task. This mechanism allows for early binding of a producer, but a later invocation.
  3. std::promise, which allows one to modify its associated std::future through its set_value() call. With this direct control over mutating a std::future, we must ensure that that the design is thread-safe if there are multiple producers (use std::mutex as necessitated).

I think SethCarnegie’s answer:

An easy way to think of it is that you can either set a future by
returning a value or by using a promise. future has no set method;
that functionality is provided by promise.

helps clarify when to use a promise. But we have to keep in mind that a std::mutex may be necessary, as the promise might be accessible from different threads, depending on usage.

Also, David’s Rodriguez’s answer is also excellent:

The consumer end of the communication channel would use a std::future
to consume the datum from the shared state, while the producer thread
would use a std::promise to write to the shared state.

But as an alternative, why not simply just use a std::mutex on a stl container of results, and one thread or a threadpool of producers to act on the container? What does using std::promise, instead, buy me, besides some extra readability vs a stl container of results?

The control appears to be better in the std::promise version:

  1. wait() will block on a given future until the result is produced
  2. if there is only one producer thread, a mutex is not necessary

The following google-test passes both helgrind and drd, confirming that with a single producer, and with the use of wait(), a mutex is not needed.

TEST

static unsigned MapFunc( std::string const& str ) 
{ 
    if ( str=="one" ) return 1u; 
    if ( str=="two" ) return 2u; 
    return 0u;
}

TEST( Test_future, Try_promise )
{
    typedef std::map<std::string,std::promise<unsigned>>  MAP; 
    MAP          my_map;

    std::future<unsigned> f1 = my_map["one"].get_future();
    std::future<unsigned> f2 = my_map["two"].get_future();

    std::thread{ 
        [ ]( MAP& m )
        { 
            m["one"].set_value( MapFunc( "one" ));
            m["two"].set_value( MapFunc( "two" ));
        }, 
      std::ref( my_map ) 
    }.detach();

    f1.wait();
    f2.wait();

    EXPECT_EQ( 1u, f1.get() );
    EXPECT_EQ( 2u, f2.get() );
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T03:59:48+00:00Added an answer on June 17, 2026 at 3:59 am

    You don’t choose to use a promise instead of the others, you use a promise to fulfill a future in conjunction with the others. The code sample at cppreference.com gives an example of using all four:

    #include <iostream>
    #include <future>
    #include <thread>
     
    int main()
    {
        // future from a packaged_task
        std::packaged_task<int()> task([](){ return 7; }); // wrap the function
        std::future<int> f1 = task.get_future();  // get a future
        std::thread(std::move(task)).detach(); // launch on a thread
     
        // future from an async()
        std::future<int> f2 = std::async(std::launch::async, [](){ return 8; });
     
        // future from a promise
        std::promise<int> p;
        std::future<int> f3 = p.get_future();
        std::thread( [](std::promise<int>& p){ p.set_value(9); }, 
                     std::ref(p) ).detach();
     
        std::cout << "Waiting...";
        f1.wait();
        f2.wait();
        f3.wait();
        std::cout << "Done!\nResults are: "
                  << f1.get() << ' ' << f2.get() << ' ' << f3.get() << '\n';
    }
    

    prints

    Waiting…Done!

    Results are: 7 8 9

    Futures are used with all three threads to get their results, and a promise is used with the third one to fulfill a future by means other than a return value. Also, a single thread can fulfill multiple futures with different values via promises, which it can’t do otherwise.

    An easy way to think of it is that you can either set a future by returning a value or by using a promise. future has no set method; that functionality is provided by promise. You choose what you need based on what the situation allows.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to ascertain some way to establish a unique ID for Chrome tabs
I'm trying to write some Python code that will establish an invisible relay between
im trying to establish and access a session from my servlet, but I can't
I'm trying to establish a HTTP persistent connection from a Silverlight application to a
I am trying to establish new SDL Tridion UI 2012 functionality on some test
I am trying to establish a https connection but my URL contains some special
I am trying to establish an abstract class. I want to ensure that any
I'm trying to establish a communication with an ONVIF camera, and I'm getting some
I'm trying to establish some way of mapping a String document to a HashMap
Just trying to establish whether prototype can do something like $$('#ID a:last').css('color','#111'); Any ideas

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.