如何在 C++ 中使用 future 和 promise 从函数线程中获取 return 值

How to get return value from function thread using future and promise in c++

我有下面的代码,我使用 futurepromise 从函数中获取 return 值。下面是代码:

void myfunction2(string msg, std::promise<std::string> && prms)
{
    prms.set_value(msg);
}

int main()
{
    std::promise<std::string> prms;
    std::future<std::string> ftr = prms.get_future();
    while (1)
    {
        thread t1(myfunction2, "Hello thread", std::move(prms));

        cout << "Main loop" << endl;

        std::string str = ftr.get();
        std::cout << str << std::endl;
        t1.join();
        Sleep(2000);
    }
}

输出如下:

Main loop
Hello thread
Main loop

因为它在 while(1) 内,所以当控件返回 std::string str = ftr.get(); 时它会抛出一些异常

Unhandled exception at 0x00007FFDD0F1A388 in Testcode.exe: Microsoft C++ exception: std::future_error at memory location 0x00000003FDCFF740.

如果我 运行 它没有 while(1) 这将起作用,但我实际上需要 运行 它在 `while(1) 循环中。我该如何解决这个问题。

您只能设置一次承诺的值。要在程序中使用循环,请将 promise 和 future 变量置于循环范围内,如下所示:

int main()
{
    int i = 0;
    while (1)
    {
        std::promise<std::string> prms;
        std::future<std::string> ftr = prms.get_future();

        thread t1(myfunction2, "Hello thread", std::move(prms));

        cout << "Main loop" << endl;

        std::string str = ftr.get();
        std::cout << str << std::endl;
        t1.join();
        Sleep(2000);

        if (++i > 3) break; // no infinite loop
    }
}

已编辑: 在您的代码中,其他线程只有在第一个线程加入后才会产生,依此类推。编辑代码片段以允许并发执行。这里所有的线程都被生成以允许并行执行,然后在最后一起加入。

int main()
{
    std::vector<std::pair<std::thread, std::future<std::string>>> threads;

    for (int i = 0; i < 5; i++)
    {
        std::promise<std::string> prms;
        std::future<std::string> fut = prms.get_future();

        thread th(myfunction2, "Hello thread", std::move(prms));
        threads.push_back(make_pair(move(th), move(fut)));
    }

    for (auto& e : threads)
    {
        auto th = move(e.first);
        auto fut = move(e.second);
        std::string str = fut.get();
        std::cout << str << std::endl;
        th.join();
    }    
}

根据:https://en.cppreference.com/w/cpp/thread/promise/set_value

An exception is thrown if there is no shared state or the shared state already stores a value or exception.

使用您的代码,您似乎试图在承诺中多次存储一个值。 其次,正如 Quimby 所指出的,在第二次迭代中,传递的 promise 已经被移动,因此没有共享状态(请参阅有关 std::promise https://en.cppreference.com/w/cpp/thread/promise/promise 的 move ctor 的文档)。对我来说,不清楚你想要达到什么目的。无论如何,请记住 std::promisestd::future 基本上是一个 one-shot 通信通道,共享状态只能设置一次。

我重写了您的代码以允许它 运行,为每次迭代创建一个新的 promise/future 对。

#include <future>
#include <iostream>
#include <thread>
#include <chrono>
#include <string>



void myfunction2(std::string msg, std::promise<std::string> && prms)
{
    prms.set_value(msg);
}

int main()
{
    while (1)
    {
        std::promise<std::string> prms;
        std::future<std::string> ftr = prms.get_future();

        thread t1(myfunction2, "Hello thread", std::move(prms));

        cout << "Main loop" << endl;

        std::string str = ftr.get();
        std::cout << str << std::endl;
        t1.join();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}