2016-05-21 5 views
4

私はC++ 11のスレッドに新たなんだと私は次のように何かをしようとしている:クラスのプライベートメソッドであるデーモンスレッドを開始しますか?

class Something { 
public: 
    void start() { 
     this->task_ = std::thread(&Something::someTask, this); 
     this->isRunning_ = true; 
     this->task_.detach(); // I read detach will stop it from hanging 
    } 

    void stop() { 
     this->isRunning = false; 
    } 

    ~Something() { 
     this->stop(); 
    }   

private: 
    std::atomic<bool> isRunning_; 
    std::thread task_; 
    void someTask() 
    { 
     while(this->isRunning_) { 
      // do something forever 
     } 
    } 
}; 

Something whatever; 
whatever.start(); 

しかし、スレッドがブロックされて取得し続けます。 whatever.start()が実行された後は何もしません。ループが実行されている間だけハングします。にスレッドの実行を待つことができます設定の同期のいくつかの種類が、ありますしない限り、

+1

を使用してdo_async_untilのコンストラクタにメンバ関数を渡す必要があるメンバ関数を使用してこの作業は 'this-> isRunning_ =この行を入れて作りますtrue; '' this-> task_ = std :: thread(&Something :: someTask、this); 'の上にあります。それ以外の場合は、条件を設定して実行させる前にスレッドループが終了することがあります。 –

+0

@πάνταῥεῖありがとう。ループは何らかの理由ですぐに終了します。 – oldjohn1994

+0

これを閉じるには投票しました。明らかにそれを話題にしない理由は、問題を再現する完全ではあるが最小限のコードが欠けているということです。さらに、トピックは誤解を招き、明らかな競合状態が見出されたが、その後無視され、テキスト中に(観察とは対照的に)あまりにも多くの解釈がある。要約すると、これは他の誰にとっても有用なエントリではありません。 –

答えて

5

これを行うには、通常のパターンは、通常std::threadを取り外し

class Something { 
public: 
    void start() { 
     this->task_ = std::thread(&Something::someTask, this); 
     // this->task_.detach(); <<<<<< Don't do that. 
    } 

    void stop() { 
     this->isRunning_ = false; 
     task_.join(); // <<< Instead of detaching the thread, join() it. 
    } 

    ~Something() { 
     this->stop(); 
    }   

private: 
    std::atomic<bool> isRunning_; 
    std::thread task_; 
    void someTask() 
    { 
     this->isRunning_ = true; 
     while(this->isRunning_) { 
      // do something forever 
     } 
    } 
}; 

で良いアイデアではありませんプロセス全体が終了する前に終了します。


Demonizing通常、バックグラウンドの子プロセスを作成し、呼び出し元に制御を返すために、親プロセスを残してfork()で実現されているプロセス。

+0

私はそれを実装しましたが、今では "アクティブ例外なしで呼び出された終了"を投げています。 – oldjohn1994

+1

私の悪い、それは動作します、デストラクタに "join()"を追加するのを忘れました、ありがとうございます – oldjohn1994

+0

runメソッドでisRunningをtrueに設定することは競合条件のレシピです。これは、スレッドを開始する前に開始する必要があります。 – Voo

1

私は最近、条件関数ブール値(ボイド)真

使用例を返すまでちょうどこの

#include<functional> 
#include<thread> 

//do action asynchronously until condition is false 
class do_async_until{ 
public: 
    do_async_until(std::function<void(void)> action, 
        std::function<bool(void)> condition); 
    ~do_async_until(); 
    void start(); 
    void stop(); 
private: 
    void _do(); 
    std::thread _worker; 
    std::function<void(void)> _action; 
    std::function<bool(void)> _condition; 
}; 
//implementation 
do_async_until::do_async_until(std::function<void(void)> action, 
       std::function<bool(void)> condition):_action(action), 
            _condition(condition){ 
} 
do_async_until::~do_async_until(){ 
    stop(); 
} 
void do_async_until::start(){ 
    _worker = std::thread(std::bind(&do_async_until::_do,this)); 
} 
void do_async_until::stop(){ 
    if(_worker.joinable()){ 
     _worker.join(); 
    } 
} 
void do_async_until::_do(){ 
    while (_condition()) 
    { 
     _action(); 
    } 
} 

が、これはsignitureボイド(空洞)で任意の関数が実行されますし、一般的なクラスを書きました:

int main(int agrc,char** argv){ 
    bool running = true; 
    auto do_this = [](){ 
     std::cout<<"hello world"<<std::endl; 
    }; 
    auto condition = [&](){ 
     return running; 
    }; 
    do_async_until async(do_this,condition); 
    async.start(); 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
    running=false; 

    return 0; 
} 

この例では、「hello world」を1秒間印刷して終了する必要があります。

EDIT:あなたは、単にあなたのクラス内do_async_untilのインスタンスを持っているとstd::bind(&foo::func,this)

+0

'async'と' future'(http://en.cppreference.com/w/cpp/thread/future)との違いは何ですか? –

+0

私の理解の中で、std :: asyncは、生成されたスレッドが長期間持続するユースケースには適していません。 std :: asyncは、私のデザインが永続的なワーカースレッドに近づいていると思うところで、1回の計算に最適です。 std :: asyncは理論的には同じ結果を得るために使用することができますが、std :: launch :: asyncを指定しても、タスクが実際に別のスレッドや場所で完了するかどうかは保証されません。 http://en.cppreference.com/w/cpp/thread/asyncを参照してください –

+0

サンプルが壊れていることがわかります - ランニングはUBを呼び出さないためにstd :: atomicでなければなりません。 – Voo

関連する問題