c++ - std::async 究竟是如何执行的?

标签 c++ multithreading c++11 asynchronous

我想知道下面的代码是如何工作的?

#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 调用的,不是吗?

最佳答案

So in the latter we miss the member function call. Why?

因为调用被推迟了。它只会在您实际请求其结果后启动,例如通过在未来调用 get()(你没有调用):

auto fut = std::async(std::launch::deferred, Task());
fut.get();

I can think that the second move constructor is called by std::future, can't I?

这是由实现定义的,是否调用复制构造函数以及调用多少次。构建它,例如in clang 甚至给了我三个调用移动构造函数的调用。因此,不要为此烦恼。但如果这样做,则必须自己研究标准库实现(如果有的话)。

关于c++ - std::async 究竟是如何执行的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50554228/

相关文章:

c++ - 模板类的不同对象的通用接口(interface)

带有 std::begin()、std::end() 问题的 C++11 自动迭代器类型

c++ - 将 QDomDocument 数据用作文本的更好方法

c# - 如何使用多维数组调用 Parallel.ForEach

java - 对于这个简单的情况,我应该使用同步块(synchronized block)吗?

python - ThreadPoolExecutor 记录? (Python)

STL - 交换的 noexcept 规范对性能有影响吗?

c++ - 使用范围解析运算符时在构造函数中调用虚方法是否安全?

c++ - clang 错误中的完整代码路径

c++ - 我需要实现一个指向成员函数重载的 C++ 函数指针