【问题标题】:Get result of future without blocking在不阻塞的情况下获得未来的结果
【发布时间】:2017-12-29 02:15:35
【问题描述】:

这个问题之前已经被问过,如果我没记错的话,读取未来结果的唯一方法是调用 get() 并阻塞直到它准备好或使用 wait_for() 持续时间为零,如中所述答案——Get the status of a std::future

但是,如果我只想让工作线程返回一个我希望它计算的结果,而不是等待或阻止自己完成,我可以不只是传递一个回调,工作线程可以在它调用时调用它吗?已经为我计算了结果?像下面这样 -

#include <iostream>
#include <thread>
#include <functional>

void foo(std::function<void(int)> callback)
{
    int result = 5;
    callback(result);
}

int main()
{
    int result = 0;
    std::thread worker(foo, [](int result) 
    {
        std::cout << "Result from worker is " << result << std::endl;
    });
    worker.join();
}   

在这里,工作线程会在为我计算结果后执行回调。我不必等待它完成或阻塞或检查循环以知道它何时准备就绪。 请建议这是一个很好的方法,因为目前没有办法在不阻塞或循环检查的情况下做到这一点?

【问题讨论】:

    标签: multithreading c++11 future


    【解决方案1】:

    您当然可以使用回调创建自己的线程,但是一旦您离开一个玩具示例,您就会注意到您可能会创建一个同步问题。这是因为您的回调是从单独的线程调用的。因此,您可能希望工作线程改为将消息发布到稍后将阅读的队列,除非没有共享状态或互斥锁已经到位。

    在您的具体示例中,让我们添加一行代码:

    int main()
    {
        std::thread worker(foo, [](int result) 
        {
            std::cout << "Result from worker is " << result << std::endl;
        });
        std::cout << "I am the main thread" << std::endl; // added
        worker.join();
    }
    

    你可能认为只有两种可能的输出:

    I am the main thread
    Result from worker is 5
    

    Result from worker is 5
    I am the main thread
    

    但其实还有其他可能的输出,比如:

    Result from worker is I am the main thread
    5
    

    所以你创建了一个错误。您要么需要在共享状态(包括 I/O)上进行同步,要么需要从主线程编排所有内容(这是阻塞或检查未来结果所提供的)。

    【讨论】:

    • “或者你需要从主线程中编排所有内容(这是阻塞或检查未来结果给你的东西” - 太好了,感谢您的澄清:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多