c++ - std::async 究竟是如何执行的?
问题描述
我想知道下面的代码是如何工作的?
#include <thread>
#include <future>
#include <set>
#include <iostream>
struct Task;
std::set<const Task*> dead_tasks;
struct Task
{
~Task() { dead_tasks.insert(this); std::cout << "dtor\n";}
Task() { std::cout << "ctor\n";}
Task(Task&&) { std::cout << "move-ctor\n";}
void operator()() const { std::cout << "func()\n"; }
};
int main(){
std::cout << dead_tasks.size() << '\n';
std::async(std::launch::async, Task());
std::cout << dead_tasks.size() << '\n';
}
此代码打印
0 ctor move-ctor move-ctor dtor func() dtor dtor 3
如果我们使用 std::launch::deferred 而不是 std::launch::async 我们将得到
0 ctor move-ctor move-ctor dtor dtor dtor 3
所以在后者中我们错过了成员函数调用。为什么?我可以理解对默认构造函数的调用和对移动构造函数的调用的存在。Task() 调用默认构造函数,然后 std::async 调用移动构造函数......但是我错过了第二次调用移动构造函数和调用成员函数背后的想法。我可以认为第二个移动构造函数是由 std::future 调用的,不是吗?
解决方案
所以在后者中我们错过了成员函数调用。为什么?
因为电话被推迟了。它只会在您实际请求其结果时开始,例如通过调用get()
未来(您没有):
auto fut = std::async(std::launch::deferred, Task());
fut.get();
我可以认为第二个移动构造函数是由 std::future 调用的,不是吗?
这是相当由实现定义的,是否会调用以及调用多少次复制构造函数。例如在 clang 中构建它甚至给了我三个对 move-constructor 的调用。因此,只是不要打扰它。但是如果你这样做了,你必须研究标准库实现本身,如果有的话。
推荐阅读
- node.js - 如何使用多个 package.json 在 docker 上运行节点安装
- android - 运行后台服务一分钟后,工具栏上的 GPS 图标消失了
- curl - 使用非零代码 cURL 命令退出会产生 404 等
- windows - 在各种描述字符串中使用 NSIS 安装程序名称
- javafx - 防止表视图中第一列的重新排序?
- python-3.x - 在python中生成时间间隔数组
- swift - UIButton 作为子视图:如何添加 IBAction
- javascript - 如何继承Odoo网站中的点击方法
- node.js - 安装 Angular CLI 时出错?
- java - 如何在 HTMLUnit 中正确使用 getByXPath?