std::future 是 C++ 标准库中的一个类模板,用于表示一个异步操作的结果,可用于从一个线程获取另一个线程计算的结果。 std::future 还可以与 std::promisestd::asyncstd::packaged_task 结合使用,用于实现更复杂的异步任务管理。

简单来说, std::future 提供了一种获取异步操作的结果的机制:

一个异步操作(通过 std::asyncstd::packaged_taskstd::promise 创建)能够向其创建者提供一个 std::future 对象,使用者可以利用 std::future 对异步操作进行查询、等待等一系列操作,如果异步操作还未产生一个结果,则这些操作可能会阻塞。当异步操作准备好将结果发送给创建者时,可以通过 promise::set_value 进行值的设定。

# 1、使用

# 1.1 与 std::promise 结合使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <thread>
#include <future>

void calculate(std::promise<int> p) {
int result = 42; // 模拟计算
p.set_value(result);
}

int main() {
std::promise<int> p;
std::future<int> f = p.get_future();

std::thread t(calculate, std::move(p));
t.join();

int result = f.get(); // 阻塞直到获取结果
std::cout << "Result: " << result << std::endl;

return 0;
}

更多关于 promise,可参考 [[promise]]

# 1.2 使用 std::async

std::async 用于启动一个异步任务并返回一个 std::future 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <future>

int calculate() {
return 42;
}

int main() {
std::future<int> f = std::async(std::launch::async, calculate);

int result = f.get(); // 阻塞直到获取结果
std::cout << "Result: " << result << std::endl;

return 0;
}

更多关于 async,可参考 [[async]]

# 1.3 与 std::packaged_task 结合使用

std::packaged_task 将可调用对象包装起来,并与 std::future 关联。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <thread>
#include <future>

int calculate() {
return 42;
}

int main() {
std::packaged_task<int()> task(calculate);
std::future<int> f = task.get_future();

std::thread t(std::move(task));
t.join();

int result = f.get(); // 阻塞直到获取结果
std::cout << "Result: " << result << std::endl;

return 0;
}

更多关于 packaged_task ,可参考 [[packaged_task]]

# 总结

std::future 是 C++ 标准库中用于管理异步操作结果的强大工具。通过与 std::promisestd::asyncstd::packaged_task 结合使用, std::future 可以实现复杂的异步任务调度和线程间通信。掌握 std::future 及其相关机制是编写高效并发程序的重要技能。

最后再来点示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <future>
#include <iostream>
#include <thread>

int main()
{
// future from a packaged_task
std::packaged_task<int()> task([]{ return 7; }); // wrap the function
std::future<int> f1 = task.get_future(); // get a future
std::thread t(std::move(task)); // launch on a thread

// future from an async()
std::future<int> f2 = std::async(std::launch::async, []{ return 8; });

// future from a promise
std::promise<int> p;
std::future<int> f3 = p.get_future();
std::thread([&p]{ p.set_value_at_thread_exit(9); }).detach();

std::cout << "Waiting..." << std::flush;
f1.wait();
f2.wait();
f3.wait();
std::cout << "Done!\nResults are: "
<< f1.get() << ' ' << f2.get() << ' ' << f3.get() << '\n';
t.join();
}

参考链接:
cppreference:future

更新于

请我喝杯咖啡吧~

Rick 微信支付

微信支付

Rick 支付宝

支付宝