Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reverse set_value() and 'deactivate' a promise?

I have a total n00b question here on synchronization. I have a 'writer' thread which assigns a different value 'p' to a promise at each iteration. I need 'reader' threads which wait for shared_futures of this value and then process them, and my question is how do I use future/promise to ensure that the reader threads wait for a new update of 'p' before performing their processing task at each iteration? Many thanks.

like image 584
MMagique Avatar asked Sep 02 '25 15:09

MMagique


2 Answers

You can "reset" a promise by assigning it to a blank promise.

myPromise = promise< int >();

A more complete example:

promise< int > myPromise;

void writer()
{
    for( int i = 0; i < 10; ++i )
    {
        cout << "Setting promise.\n";
        myPromise.set_value( i );

        myPromise = promise< int >{};       // Reset the promise.

        cout << "Waiting to set again...\n";
        this_thread::sleep_for( chrono::seconds( 1 ));
    }
}

void reader()
{
    int result;
    do
    {
        auto myFuture = myPromise.get_future();
        cout << "Waiting to receive result...\n";
        result = myFuture.get();
        cout << "Received " << result << ".\n";
    } while( result < 9 );
}

int main()
{
    std::thread write( writer );
    std::thread read( reader );

    write.join();
    read.join();

    return 0;
}

A problem with this approach, however, is that synchronization between the two threads can cause the writer to call promise::set_value() more than once between the reader's calls to future::get(), or future::get() to be called while the promise is being reset. These problems can be avoided with care (e.g. with proper sleeping between calls), but this takes us into the realm of hacking and guesswork rather than logically correct concurrency.

So although it's possible to reset a promise by assigning it to a fresh promise, doing so tends to raise broader synchronization issues.

like image 134
OldPeculier Avatar answered Sep 05 '25 03:09

OldPeculier


A promise/future pair is designed to carry only a single value (or exception.). To do what you're describing, you probably want to adopt a different tool.

If you wish to have multiple threads (your readers) all stop at a common point, you might consider a barrier.

like image 38
Managu Avatar answered Sep 05 '25 05:09

Managu