2016-08-17 2 views
2

スレッドのセットを同期しようとしています。これらのスレッドは、ほとんどの場合、自分の予定された仕事をするために目を覚ます。私はstd::threadを使っています。std :: condition_variable(ロックなし)

私はアプリケーションスレッドを終了すると、終了しないようにしています。 C#ではスレッドをbackgroundにすることができますので、アプリの終了時にtermiantedになります。 C++ではequavalint機能が利用できないようです。

私は一種のイベントインジケータを使用して、アプリケーション終了時にスレッドを起動させることにしました。標準C++ 11 std::condition_variableは一意のロックを必要とするので、私は両方のスレッドが同時に起動する必要がある(リソースを共有しない)ので、使用できません。

最終的に、問題を解決するためにWinApiのCreateEvent + SetEvent + WaitForSingleObjectを使用することにしました。

私はちょうどC++ 11を使用して同じ動作を達成する方法がありますか?再び

、私が何をしたいです:

  1. スレッドのセットは、独立して作業し、通常、特定の期間のために 眠っているされている(別のスレッドのために異なる可能性があります。
  2. すべてthredsは変数をチェック。それは(私は、この変数IsAlivaを呼び出す)動作を停止する時間である かどうか、それらのすべてのために空くです 実際にすべてのスレッドは、次のようにループ内で回転している:

    while (IsAlive) { 
        // Do work 
        std::this_thread::sleep_for(...); 
    } 
    
  3. スレッドは、互いにブロックしないで同時に動作することができなければなりません。
  4. アプリが終了してイベントが発生して、今すぐにスレッドを 目覚めさせても、タイムアウトには関係ありません。
  5. が起動すると、 IsAliveをチェックして終了します。
+0

ポイント4と5は分かりません。 – Zereges

+0

イベントによって、タイムアウトが終了する前にスレッドが起きるようになります。 – Ivan

+0

* "彼らはリソースを共有しません" *と* "すべてのスレッドは変数をチェックします[..]' IsAlive' "*は互換性がありません。 – Jarod42

答えて

3

はい、あなたがこの状態に入る前にトリガされる死の顔で正しく動作することを条件変数のこの使用して、標準C++のメカニズム、ミューテックスとsomekind

// Your class or global variables 
std::mutex deathLock; 
std::condition_variable deathCv; 
bool deathTriggered = false; 

// Kill Thread runs this code to kill all other threads: 
{ 
    std::lock_guard<std::mutex> lock(deathLock); 
    deathTriggered = true; 
} 
deathCv.notify_all(); 

// You Worker Threads run this code: 
while(true) 
{ 
    ... do work 

    // Now wait for 1000 milliseconds or until death is triggered: 
    std::unique_lock<std::mutex> lock(deathLock); 
    deathCv.wait_for(lock, std::chrono::milliseconds(1000), [](){return deathTriggered;}); 

    // Check for death 
    if(deathTriggered) 
    { 
     break; 
    } 
} 

注意のフラグを行うことができます。 wait_forからの戻り値を使用することもできますが、この方法では読みやすくなります。また、wait_forコードがスリープ中にunique_lockを内部的にロック解除し、条件を確認するために再取得し、また復帰したときに、wait_forコードが内部的にロックを解除するため、スリープ中の複数のスレッドは問題ありません。

最後に、すべてのスレッドは、ブールフラグをチェックする際にシリアル化されている間に「同時に」起動します。これは、いくつかの命令の場合にのみ、ロックからロックを解除します。それは目立たないでしょう。

1

C++ 11では、detach()にスレッドを割り当てることができます。そのため、デーモンスレッドとして扱われます。つまり、アプリケーションが終了すると自動的にスレッドが停止します。

+0

スレッドを切り離してメインから戻ることにはいくつかの危険があることに注意してください - http://stackoverflow.com/questions/19744250/what-happens-to-a-detached-thread-when-main-exits –

関連する問題