如何在 C++ 中使用 future 和 promise 从函数线程中获取 return 值
How to get return value from function thread using future and promise in c++
我有下面的代码,我使用 future
和 promise
从函数中获取 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::promise
和 std::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));
}
}
我有下面的代码,我使用 future
和 promise
从函数中获取 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::promise
和 std::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));
}
}