在c++中,如何使用 Future 对象判断异步线程的返回值
时间: 2024-03-07 17:48:26 浏览: 118
在 C++11 及以上版本中,可以使用 std::future 对象来获取异步线程的返回值。具体步骤如下:
1. 在开启异步线程时,使用 std::async 函数创建一个 std::future 对象,并将异步线程的返回值赋值给该对象:
```c++
std::future<int> future = std::async(std::launch::async, [](){
// 异步线程任务
return 42;
});
```
2. 在需要获取异步线程的返回值时,可以调用 std::future 对象的 get 方法,该方法会阻塞当前线程直到异步线程完成任务并返回结果,然后返回异步线程的返回值:
```c++
int result = future.get();
```
需要注意的是,get 方法只能调用一次,多次调用会抛出 std::future_error 异常。如果异步线程抛出了异常,get 方法会将其重新抛出。如果不想阻塞当前线程,也可以使用 std::future 对象的 wait_for 或 wait_until 方法来等待异步线程的返回值。
相关问题
c++中如何获取线程的返回值
在C++中,获取线程的返回值可以通过以下步骤完成:
1. 使用`std::thread`类创建一个线程,并指定要运行的函数或可调用对象。
2. 在创建线程时,将返回值存储在一个变量中,通常是使用`std::future`类。
3. 在线程执行完毕后,使用`std::future::get()`函数来获取返回值。
下面是一个示例代码:
```cpp
#include <iostream>
#include <thread>
#include <future>
int foo()
{
// 执行一些操作
return 42;
}
int main()
{
std::future<int> result = std::async(std::launch::async, foo); // 创建线程并获取返回值
// 其他操作...
int returnValue = result.get(); // 获取返回值
std::cout << "返回值为: " << returnValue << std::endl;
return 0;
}
```
在上面的示例中,`std::async()`函数用于创建一个异步任务,并将返回值存储在`std::future`对象中。然后,我们使用`std::future::get()`函数来获取线程的返回值。
C++多线程函数返回值
### C++ 多线程函数返回值实现方法
#### 使用 `std::async` 和 `std::future`
为了使C++中的多线程函数能够拥有返回值,一种常见的方式是利用`std::async`配合`std::future`。这种方式下,当调用`std::async`时会立即得到一个`std::future`类型的对象,该对象用于稍后获取由异步操作产生的结果。
```cpp
#include <iostream>
#include <thread>
#include <future>
using namespace std;
// 定义一个简单的返回整数的函数
int simpleFunction() {
this_thread::sleep_for(chrono::seconds(1)); // 模拟耗时操作
return 42;
}
void demonstrateAsyncWithReturnValue() {
// 启动异步任务并获得future对象
future<int> resultFuture = async(launch::async, simpleFunction);
// 执行其他工作...
// 获取异步任务的结果
try {
int value = resultFuture.get();
cout << "The returned value is: " << value << endl;
} catch (exception& e) {
cerr << "Exception caught: " << e.what() << '\n';
}
}
```
上述代码展示了如何定义一个带有返回值的任务,并通过`std::future::get()`来捕获这个返回值[^2]。
#### 利用 `std::packaged_task` 或者 `std::promise`
对于更复杂的场景或是想要手动控制线程生命周期的情况,则可以选择使用`std::packaged_task`或者是`std::promise`。这两种方式允许更加灵活地设置和传递返回值给主线程或其他等待接收结果的地方。
##### Packaged Task 方法
```cpp
#include <iostream>
#include <functional>
#include <future>
#include <thread>
using namespace std;
void taskPackaged(int num, packaged_task<int()> &pt) {
pt.set_value(num * 2); // 设置返回值
}
void showPackagedTaskUsage() {
packaged_task<int()> pt([]()->int{
this_thread::sleep_for(std::chrono::milliseconds(500));
return 88; });
future<int> fut = pt.get_future();
thread th(bind(&taskPackaged, 77, ref(pt)));
th.join();
cout << "Result from packaged_task: " << fut.get() << "\n";
}
```
这里创建了一个`std::packaged_task`实例,并将其绑定到lambda表达式的可调用实体上。之后,在子线程中设置了实际计算出来的返回值并通过`set_value()`提交回去[^3]。
##### Promise 方法
```cpp
#include <iostream>
#include <memory>
#include <utility>
#include <string>
#include <thread>
#include <future>
using namespace std;
void doWork(promise<string>& prom) {
string msg("Hello!");
this_thread::sleep_for(chrono::seconds(1));
prom.set_value(msg); // 将字符串作为返回值设定进去
}
void illustratePromiseUseCase() {
auto prmsPtr = make_shared<promise<string>>();
future<string> ftrStr = prmsPtr->get_future();
thread t(doWork, move(*prmsPtr));
cout << "Waiting for the message...\n";
string receivedMsg = ftrStr.get(); // 阻塞直到拿到消息
cout << "Message received: '" << receivedMsg << "'\n";
t.join();
}
```
在这个例子中,`doWork`函数接受一个指向`std::promise<std::string>`的对象指针,并在其内部完成某些逻辑运算后将最终结果存入其中。而主线程则可以通过关联好的`std::future`对象同步读取这些数据。
阅读全文