2017-10-24 6 views
-1

私は非同期の方法でいくつかの関数を実行しようとしています。この目的のために、Coreというクラスを作成しました。ここでは、別のスレッドで関数を実行するのにstd::asyncを使用し、std::shared_future<int>を使用してこのスレッドを待って、将来の結果を得ることができます。このエラーとstd :: asyncとstd :: shared_futureがプログラムを停止させます

std::cout << "Boom" << std::endl; // Error occurs here 

#include <iostream> 
#include <future> 

class Core : public std::enable_shared_from_this<Core> 
{ 
public: 
    Core() 
     : isRunning_(false) { 
    }; 
    ~Core() { 
     isRunning_ = false; 
     if (f_.valid()) 
     { 
      f_.wait(); 
      std::cout << "Result is: " << f_.get() << std::endl; 
     } 
    }; 
    void Start() { 
     isRunning_ = true; 
     auto self(shared_from_this()); 
     f_ = std::async(std::launch::async, [self, this]() { 
      try { 
       while (true) { 
        if (!isRunning_) 
         break; 

        std::cout << "Boom" << std::endl; // Error occurs here 
        std::this_thread::sleep_for(std::chrono::seconds(1)); 
       } 
      } 
      catch (const std::exception& e) { 
       std::cerr << "Loop error:" << e.what(); 
      } 
      return 999; 
     }); 
    } 

private: 
    std::shared_future<int> f_; 
    std::atomic<bool> isRunning_; 
}; 

int main() 
{ 
    try { 
     std::shared_ptr<Core> load(new Core); 
     load->Start(); 

     throw std::runtime_error("Generate error"); // Added in order to generate error 
    } 
    catch (const std::exception& e) { 
     std::cout << "Error occurred: " << e.what(); 
    } 

    return 0; 
} 

私はそれがこのラインでクラッシュし、このプログラムを起動するたび:これはテストプログラムのコードである

Error output

私はデバッグ中に取得できたデバッガエラーとコールスタックです:

enter image description here

Coreデストラクタ関数がまったく呼び出さないように見えます。それはなぜ起こるのですか?奇妙な!!!

私のミスはどこに教えてください。ありがとう。

+0

エラーは何ですか? –

+0

エラーの説明はありません...プログラムはただちに終了します – definename

+0

デバッガを使用してコードをステップ実行する方法を学ぶ必要があるようです。良いデバッガを使用すると、プログラムを1行ずつ実行し、どこからずれているかを確認することができます。これはプログラミングをする場合に不可欠なツールです。さらに読む:[小さなプログラムをデバッグする方法](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – NathanOliver

答えて

2

メインスレッドがmain()から復帰すると、プロセス全体を終了する前に環境を破棄し始めます。このすべてはバックグラウンドスレッドがオブジェクトにアクセスしている間に破棄されているか、すでに破棄されています。

は、私はあなたが達成するためにtriyingされているかわからないですが、あなたは何か間違ったことをやっている:

  • いくつかの作業を実行し、それが例えば行われた後、すぐに返す必要がありますあなたのラムダ永遠に繰り返すべきではありません。
  • あなたのメインスレッドは、std::future<T>::get()に電話することで、あなたの未来が完了するのを待つべきです。
+0

しかし、私は 'Core'デストラクタで未来を待っていて、ループ終了前に' Core'オブジェクトが破壊されるのを防ぎます。 – definename

+0

を参照してください。問題は、あなたのスレッドがtry-catchブロックを終了して 'Core'インスタンスへの共有ポインタを破壊すると、バックグラウンドスレッドは依然として参照を保持しているので、デストラクタは決して呼び出されず、決して呼び出されません。あなたは '[self、this]'を実行したときにバックグラウンドスレッドにそのポインタを渡しました。 – Ivan

+0

しかし、 'self'は' Core'オブジェクトへの共有ポインタです – definename

関連する問題