使用 stdasync 而不是 stdthread

std::async 也能够制作线程。与 std::thread 相比,当你只想异步运行函数时,它被认为功能较弱但更易于使用。

异步调用函数

#include <future>
#include <iostream>

unsigned int square(unsigned int i){
    return i*i;
}

int main() {
    auto f = std::async(std::launch::async, square, 8);
    std::cout << "square currently running\n"; //do something while square is running
    std::cout << "result is " << f.get() << '\n'; //getting the result from square
}

常见的陷阱

  • std::async 返回一个 std::future,它保存将由函数计算的返回值。当 future 被破坏时,它会一直等到线程完成,使你的代码有效地单线程化。当你不需要返回值时,这很容易被忽略:

    std::async(std::launch::async, square, 5);
    //thread already completed at this point, because the returning future got destroyed
    
  • std::async 在没有发布策略的情况下工作,所以 std::async(square, 5); 编译。当你这样做时,系统决定是否要创建一个线程。这个想法是系统选择创建一个线程,除非它已经运行了比它可以有效运行更多的线程。不幸的是,实现通常只选择不在该情况下创建线程,因此你需要使用 std::launch::async 覆盖该行为,这会强制系统创建线程。

  • 小心竞争条件。

更多关于期货和承诺的异步