C++多线程函数返回值
时间: 2024-12-31 21:34:52 浏览: 14
### 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`对象同步读取这些数据。
阅读全文