如何反转set_value()和'停用'承诺?

时间:2011-06-30 21:34:44

标签: c++ synchronization boost-thread future promise

我在这里有一个关于同步的总n00b问题。我有一个'writer'线程,它在每次迭代时为promise提供不同的值'p'。我需要'读者'线程等待这个值的shared_futures然后处理它们,我的问题是如何使用future / promise来确保读者线程在执行处理任务之前等待'p'的新更新每次迭代?非常感谢。

2 个答案:

答案 0 :(得分:1)

promise / future对旨在仅包含一个值(或例外)。要做你正在描述的事情,你可能想要采用不同的工具。

如果您希望多个主题(您的读者)都停留在公共点,您可以考虑barrier

答案 1 :(得分:1)

你可以重置"通过将其分配给空白的承诺来承诺。

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() 1}}在重置承诺时调用。可以小心避免这些问题(例如,在调用之间正常休眠),但这会将我们带入黑客和猜测领域而不是逻辑上正确的并发性。

因此,虽然可以通过将承诺分配给新的承诺来重置承诺,但这样做往往会引发更广泛的同步问题。