Как мне отменить set_value () и «деактивировать» обещание? - PullRequest
2 голосов
/ 01 июля 2011

У меня есть вопрос n00b о синхронизации. У меня есть поток «писатель», который назначает разные значения «р» для обещания на каждой итерации. Мне нужны потоки 'reader', которые ждут shared_futures с этим значением и затем обрабатывают их, и мой вопрос заключается в том, как мне использовать future / обещание, чтобы потоки считывателя ожидали нового обновления 'p', прежде чем выполнять свою задачу обработки в каждая итерация? Большое спасибо.

Ответы [ 2 ]

1 голос
/ 25 февраля 2015

Вы можете «сбросить» обещание, назначив его пустому обещанию.

myPromise = promise< int >();

Более полный пример:

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;
}

Однако проблема с этим подходом заключается вэта синхронизация между двумя потоками может заставить писателя вызывать promise::set_value() более одного раза между вызовами читателя на future::get() или future::get() для вызова во время сброса обещания.Этих проблем можно избежать с осторожностью (например, при правильном сне между вызовами), но это приводит нас к царству взлома и догадок, а не к логически правильному параллелизму.

Таким образом, хотя можно сбросить обещание, назначив егок новому обещанию, это приводит к более широким проблемам синхронизации.

1 голос
/ 01 июля 2011
Пара

A promise / future предназначена для переноса только одного значения (или исключения). Чтобы сделать то, что вы описываете, вы, вероятно, захотите использовать другой инструмент.

Если вы хотите, чтобы несколько потоков (ваших читателей) останавливались на одной точке, вы можете рассмотреть barrier.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...