使用 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 覆蓋該行為,這會強制系統建立執行緒。

  • 小心競爭條件。

更多關於期貨和承諾的非同步