1. future:
future的引入是为了解决thread并不提供直接接收返回值的机制的问题。
std::thread 的设计理念是:
只负责调度和执行线程函数,不负责管理其结果。
比如:
int do_work() {
return 42;
}
int main() {
std::thread t(do_work); // 编译通过,但返回值 42 被忽略了
t.join();
}
所以,如果你想要线程函数返回值,你需要使用 std::future 配合 std::async 或 std::promise 来实现。
2. async
可以使用 std::async 启动一个异步任务。和std::thread不同, std::async 会返回一个 std::future 对象,这个对象持有最终计算出来的结果。当需要这个值时,只需要调用这个对象的get()成员函数;它阻塞线程直到期望值状态为就绪为止。
#include <future>
#include <iostream>
int do_work() {
return 42;
}
int main() {
std::future<int> result = std::async(std::launch::async, do_work);
std::cout << "Result: " << result.get() << std::endl;
return 0;
}
async传参的方式和thread一样:
#include <string>
#include <future>
struct X
{
void foo(int,std::string const&);
std::string bar(std::string const&);
};
X x;
auto f1=std::async(&X::foo,&x,42,"hello");
// 调用p->foo(42,"hello"),p是指向x的指针
auto f2=std::async(&X::bar,x,"goodbye");
// 调用tmpx.bar("goodbye"), tmpx是x的拷贝副本
struct Y
{
double operator()(double);
};
Y y;
auto f3=std::async(Y(),3.141);
// 调用tmpy(3.141),tmpy通过Y的移动构造函数得到
auto f4=std::async(std::ref(y),2.718);
// 调用y(2.718)
X baz(X&);
std::async(baz,std::ref(x));
// 调用baz(x)
class move_only
{
public:
move_only();
move_only(move_only&&)
move_only(move_only const&) = delete;
move_only& operator=(move_only&&);
move_only& operator=(move_only const&) = delete;
void operator()();
};
auto f5=std::async(move_only());
// 调用tmp(),tmp是通过std::move(move_only())构造得到
async第一个参数可选:
This parameter is of the type std::launch,
and can either be std::launch::deferred to indicate that the function call is to be
deferred until either wait() or get() is called on the future, std::launch::async to
indicate that the function must be run on its own thread, or std::launch::deferred
| std::launch::async to indicate that the implementation may choose. This last
option is the default. If the function call is deferred, it may never run.
代码说明:
auto f6=std::async(std::launch::async,Y(),1.2);
// 在新线程上执行
auto f7=std::async(std::launch::deferred,baz,std::ref(x));
// 在wait()或get()调用时执行
auto f8=std::async(
std::launch::deferred | std::launch::async,
baz,std::ref(x));
// 实现选择执行方式
auto f9=std::async(baz,std::ref(x));
f7.wait();
//调用延迟函数
3. packaged_task
#include <deque>
#include <mutex>
#include <future>
#include <thread>
#include <utility>
std::mutex m;
std::deque<std::packaged_task<void()> > tasks;
bool gui_shutdown_message_received();
void get_and_process_gui_message();
void gui_thread()
{
while(!gui_shutdown_message_received())
{
get_and_process_gui_message();
std::packaged_task<void()> task;
{
std::lock_guard<std::mutex> lk(m);
if(tasks.empty())
continue;
task=std::move(tasks.front());
tasks.pop_front();
}
task();
}
}
std::thread gui_bg_thread(gui_thread);
template<typename Func>
std::future<void> post_task_for_gui_thread(Func f)
{
std::packaged_task<void()> task(f);
std::future<void> res=task.get_future();
std::lock_guard<std::mutex> lk(m);
tasks.push_back(std::move(task));
return res;
}
4. promise
#include <iostream>
#include <thread>
#include <future>
void do_work(std::promise<int> p) {
p.set_value(42);
}
int main() {
std::promise<int> p;
std::future<int> f = p.get_future();
std::thread t(do_work, std::move(p));
std::cout << "Result: " << f.get() << std::endl;
t.join();
}
759

被折叠的 条评论
为什么被折叠?



