2016-11-24 7 views
5

は私が持っているコードでハング:私は5秒後に出力でご覧結果タイマーは、私がここで標準環境 とタイマーを実装しようとしているメインスレッド

bool shutdownDetected = false; 

void signal_handler(const int sigid) 
{ 
    shutdownDetected = true; 
} 

int main(int argc, const char * argv[]) 
{ 
    signal(SIGTERM, (sig_t)signal_handler); 

    std::async(std::launch::async, [&]() { 
     std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
     std::cout << "On TIMER!" << std::endl; 
    }); 

    std::cout << "main function" << std::endl; 

    while (!shutdownDetected) { 
    } 

    return EXIT_SUCCESS; 
} 

// 5 seconds left 
On Timer 
main function 

が、表示させたい:

main function 
// 5 seconds left 
On Timer 

私の実装がメインスレッドもハングアップしているようです。これを避ける方法は?

+1

私は専門家だが、私はそれは奇妙あなたが'に.getを(呼び出してはいけないことを見つける。) 'http://en.cppreference.com/w/cpp /スレッド/未来)。 [もし望むなら、意図した結果が得られます。](http://coliru.stacked-crooked.com/a/f04caae880926851) – Borgleader

+0

実際に 'get'を呼び出す必要はありません。後で 'get'を呼び出すことができるように、' future'を何かに割り当てる必要があります。 – user4581301

+0

@ user4581301一時的に一時的に破壊され、詐欺が起こる前にメインスレッドをハングアップするので、Ohhh? – Borgleader

答えて

3

std :: asyncコマンドはstd :: futureを返し、すぐに破棄されます。問題は未来を破壊するには、あなたが作成したスレッドに「参加」する必要があるということです。つまり、デストラクタはスレッドが終了してメインスレッドのコード実行が完了するまで進行しません。

単純な答えは、std :: async呼び出しの結果を変数に代入し、可能であれば、終了テストを行うループのget()メンバー関数を呼び出します。

auto t = std::async(std::launch::async, [&]() { 
    std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
    std::cout << "On TIMER!" << std::endl; 
}); 

std::cout << "main function" << std::endl; 

t.get(); 
3
std::async(std::launch::async, [&]() { 
     std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
     std::cout << "On TIMER!" << std::endl; 
    }); 

あなたが変数にstd::asyncによって返さstd::futureを割り当てて、それを周りに保つない限り動作しません。私はこれをなぜ見ているのか分かりませんでした。なぜなら、私はそれを調べるのに気を使うことができなかったからです。ヴィンセントSavardがした、と述べていたdestructor for std::future上のドキュメントに私たちをリンク:

を次のすべてに該当する場合、それはブロックすることがあります。共有状態ははstdする::非同期の呼び出しによって作成された、共有状態でありますこれは共有状態への最後の参照です。

returnded std::futureは何にも割り当てられていないため、即座に破棄され、デストラクタは完了するまでブロックします。

シグナルハンドラは問題に関連していないので除外します。 [ `のstd :: future`](上

#include <iostream> 
#include <future> 

int main() 
{ 
    auto letMeLive = std::async(std::launch::async, []() { 
     std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
     std::cout << "On TIMER!" << std::endl; 
    }); 

    std::cout << "main function" << std::endl; 

    letMeLive.wait(); // instead of the signal handler 
    return EXIT_SUCCESS; 
}