2017-08-22 24 views
3

私のプロジェクトでは、n秒ごとにデバイスをポーリングしてスリープして永遠に続ける必要があります。 std::threadの代わりにasyncとして起動して非同期タスクを作成しました。しかし、私がstd::this_thread::sleep_for()を非同期タスクとして使用して、非同期として起動すると、実際にメインスレッドがブロックされているように見えますか? 以下のプログラムは "Inside Async .."を永久に出力しますが、 "Main function"は決して出力しません。非同期タスクをスリープ

std::thread()を使用すると、非同期の代わりに正常に動作します。しかし、私はそれに参加する必要はありませんし、スレッドとは異なり、その寿命を管理するので、非同期タスクを使用したいと思います。

非同期タスクをスリープ状態にする方法を教えてください。

#include <iostream> 
#include <future> 
#include <thread> 

int main() 
{ 
    std::async(std::launch::async, 
    []() 
    { 
     while(true) 
     { 
      std::cout <<"Inside async.."<< std::endl; 
      std::this_thread::sleep_for(std::chrono::seconds(2)); 
     } 
    }); 

    std::cout <<"Main function"<< std::endl; 
    return 0; 
} 
+0

単にスレッドを切り離すと、「スレッドに参加する必要はなくなり、スレッドのライフタイムを管理できます。 –

+0

これについて、[documentation](https://stackoverflow.com/documentation/c%2b%2b/699/threading/4745/using-stdasync-instead-of-stdthread)があった時がありました。 – nwp

+0

@samvarあなたのプログラムをきれいに終了させたい場合は、切り離しは簡単ではありません。 – Yakk

答えて

6

std::asyncそのデストラクタで終了するタスクを待つstd::futureを返します。 std::futureをどこかに保存してデストラクタを遅らせる:

auto future = std::async(...)

+0

これは、 'std:.async'が厳密に非同期的に実行する必要はないことに注意してください(スタンダードは"新しいスレッドの実行時と同じように... _as if_、それが何であれ)。とにかくそれは最良のアイデアではないかもしれません。 – Damon

2

std::asyncは、すぐに破棄されるstd::futureを返します(const参照によって延長されていないか、またはオブジェクトに移動された一時的なものです)。

std::futureのデストラクタは、std::futureという非同期の結果が終了するまでブロックします。あなたの非同期タスクが終了していないので、std::asyncの呼び出しは永遠にブロックされます。

将来の寿命を延ばすことは助けになりません。デストラクタはいつかブロックされるため、非同期タスクは終了しないためです。 std::threadを使用してここに適切と思われます。

実際、私はあなたが望むものは定期的に実行される非同期タスクであるため、第三者のタイマー実装を使用することをお勧めします。これはタイマーに最適です。

+1

デストラクタはある時点で、通常は 'main'が終了する前にブロックします。 – nwp

+0

@nwp非同期タスクの結果が気にならなければ、ブロックしたくないでしょう。 –

+0

私は、メインスレッドよりも寿命の長いスレッドについて標準が何を言っているのか分かりません。私はそれがOKではないと思う。 – nwp