C++並發高級接口:std::async和std::future


std::async和std::future

std::async創建一個后台線程執行傳遞的任務,這個任務只要是callable object均可,然后返回一個std::future。future儲存一個多線程共享的狀態,當調用future.get時會阻塞直到綁定的task執行完畢:

#include <iostream>
#include <future>

void task() {
    for (int i = 0; i < 10; i++) {
        std::cout << "A";
    }
}

int main() {
    std::future<void> result{ std::async(task) };
    for (int i = 0; i < 10; i++) {
        std::cout << "B";
    }
    result.get();	//強制阻塞main線程,直到task線程執行完畢
    system("pause");
    return 0;
}

std::launch::async

上面task返回void,這個結果沒用,我們只是單純的想等待任務線程結束。
對這種需求還可以用更簡單的方法:指定一個launch policy

#include <iostream>
#include <future>

void task() {
    for (int i = 0; i < 10; i++) {
        std::cout << "A";
    }
}

int main() {
    std::future<void> result{ std::async(std::launch::async,task) };
    for (int i = 0; i < 10; i++) {
        std::cout << "B";
    }
    system("pause");
    return 0;
}

在創建async的時候指定一個launch policy,連result.get都可以不用了,不過還是需要把async的返回值賦給result。如果不賦值async會和同步調用一樣在這里阻塞直到調用完畢,相當於沒用async。

總共有兩種launch policy:

  • std::launch::async 當返回的future失效前會強制執行task,即不調用future.get也會保證task的執行
  • std::launch::deferred 僅當調用future.get時才會執行task
    如果創建async時不指定launch policy,他會默認std::launch::async|std::launch::deferred,根據情況選一種執行

std::launch::deferred

再來試試std::launch::deferred策略。

#include <iostream>
#include <future>

void task() {
    for (int i = 0; i < 10; i++) {
        std::cout << "A";
    }
}

int main() {
    std::future<void> result{ std::async(std::launch::deferred,task) };
    for (int i = 0; i < 10; i++) {
        std::cout << "B";
    }
    result.get();
    system("pause");
    return 0;
}

程序輸出BBBBBBBBBBAAAAAAAAAA,和我們說的一樣,創建async的時候它並沒有開啟新線程執行任務,而是等到result.get的時候才執行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM