代码之家  ›  专栏  ›  技术社区  ›  vollitwr

STD:如何执行异步?

  •  1
  • vollitwr  · 技术社区  · 7 年前

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

    #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';
    }
    

    此代码打印

    零 阴极射线管 移动ctor 移动ctor 德托尔 函数() 德托尔 德托尔 三

    如果STD::启动::推迟而不是STD::启动::异步,我们将得到

    零 阴极射线管 移动ctor 移动ctor 德托尔 德托尔 德托尔 三

    所以在后一种情况下,我们会错过成员函数调用。为什么?我可以理解对默认构造函数的调用和对移动构造函数的调用的存在性。Task()调用默认构造函数,然后STD::Aysic调用移动构造函数…但是,我错过了对move构造函数的第二次调用和对成员函数的调用背后的想法。我可以认为第二步构造函数是由STD::未来,不是吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Jodocus    7 年前

    所以在后一种情况下,我们会错过成员函数调用。为什么?

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

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

    我可以认为第二步构造函数是由STD:: 我不能吗?

    这是一个实现,它定义了是否以及有多少对复制构造函数的调用。例如,在Clang中构建它,甚至给了我三个对move构造函数的调用。所以,不要为它操心。但是,如果这样做了,那么您必须查看标准库实现本身(如果可用)。