c++ std::asyncで非同期実行

std::asyncで関数の非同期実行ができる。

std::asyncの戻り値であるfutureを使って、

  • 関数の実行終了を待つ (wait)
  • 関数の実行終了をタイムアウト時間指定で待つ (wait_for)
  • 関数の実行結果を受け取る (get)

ことができる。

また、std::asyncの実行ポリシーによって

  • 別スレッドで実行する
  • すぐには実行せず、後で実行する

ことができる。

#include <iostream>
#include <future>
#include <chrono>

using namespace std::literals;
int main(){
    {
        std::cout << "start " << std::chrono::system_clock::now() << '\n';
        auto f = std::async(std::launch::async, [](){
            std::cout << "thread start " << std::chrono::system_clock::now() << '\n';
            std::this_thread::sleep_for(2s);
        });
    
        // 終了を待つ
        f.wait();
        std::cout << "end " << std::chrono::system_clock::now() << "\n\n";
    }
    {
        std::cout << "start " << std::chrono::system_clock::now() << '\n';
        auto f = std::async(std::launch::async, [](){
            std::cout << "thread start " << std::chrono::system_clock::now() << '\n';
            std::this_thread::sleep_for(2s);
        });
    
        // 終了を待つ (ただし、1秒でタイムアウト)
        auto result = f.wait_for(1s);
        std::cout << ((result == std::future_status::timeout) ? "timeout" : "") << '\n';
        std::cout << "end " << std::chrono::system_clock::now() << "\n\n";
    }
    {
        std::cout << "start " << std::chrono::system_clock::now() << '\n';
        auto f = std::async(std::launch::async, []() -> int{
            std::cout << "thread start " << std::chrono::system_clock::now() << '\n';
            std::this_thread::sleep_for(2s);
            return 123;
        });
    
        // 終了を待って結果を取得 
        auto result = f.get();
        std::cout << result << '\n';
        std::cout << "end " << std::chrono::system_clock::now() << "\n\n";
    }
    {
        std::cout << "start " << std::chrono::system_clock::now() << '\n';
        // 遅延実行
        auto f = std::async(std::launch::deferred, []() -> int{
            std::cout << "thread start " << std::chrono::system_clock::now() << '\n';
            std::this_thread::sleep_for(2s);
            return 123;
        });
    
        std::this_thread::sleep_for(1s);
        // 終了を待って結果を取得 
        auto result = f.get();
        std::cout << result << '\n';
        std::cout << "end " << std::chrono::system_clock::now() << "\n\n";
    }
/* 
start 2022-09-12 03:37:02.2842713
thread start 2022-09-12 03:37:02.2899610
end 2022-09-12 03:37:04.2908115

start 2022-09-12 03:37:04.2909026
thread start 2022-09-12 03:37:04.2910574
timeout
end 2022-09-12 03:37:05.2954522

start 2022-09-12 03:37:06.3097559
thread start 2022-09-12 03:37:06.3099622
123
end 2022-09-12 03:37:08.3127969

start 2022-09-12 03:37:08.3128716
thread start 2022-09-12 03:37:09.3226742
123
end 2022-09-12 03:37:11.3310814
*/
}