2016-07-06 6 views
1

特定のトリガーイベントがクラスFooの内部で受信されたときスレッドを生成する必要があります。トリガーイベントは、変数triggerEventへの参照を持つWinsockサーバークラスによって受信されます。オブジェクト指向のイベント駆動型アプリケーションでのスレッド

bool Foo::HandleEvents() 
{ 
    while (1) 
    { 
     // Other things are done at the top of this loop 

     switch (triggerEvent) 
     { 
      case 'h': 
      { 
       // I instantiate an object here to do 
       // what I need to do in the thread. 
       // I use a pointer that is a private 
       // member of Foo. 
       thingMaker = new ThingMaker(params); 

       // Spawn a new thread here calling a 
       // function of ThingMaker and using thingMaker 
       break; 
      } 
      case ...: return true; 
      default: break; 
     } 
    } 
} 

スレッドがswitchでその場合にローカルであるので、私はbreakにそれへのアクセスを失います。私はjoin()に電話することはできません。なぜなら、私はリアルタイム処理を扱っており、すでに完了していない限り、スレッドが終了するのを待つことができないからです。

最近、私は同じアプリケーションに関してhereスレッディングに関する質問をしましたが、detach()は悪い習慣であると言われました。私の質問はあまりにも漠然としていると思います。私のニーズに合っていないソリューションが提供されてしまったので、私のアプリケーションはその後アーキテクチャが変わっています。

私はまた、ThingMakerのインスタンスを作成する無駄なマネージャークラスのスレッドをカプセル化しようとしました。

どうすればよいですか?私の主な問題は範囲だと思うが、私の選択肢は限られている。 Foo::HandleEvents()をまったく遅らせることはできません。そうしないと、重要なデータが失われます。

+3

投稿されたコードが、あなたの 'params'をディスパッチする作業のためにプールによって監視されるキューにポストするスレッドプールのような、スレッドのライフタイムを制御するシステムを考えましたか? – WhozCraig

+0

'futures'を扱うのはどうですか? C++ 11はありますか? – Arunmu

+1

'スレッド'を 'Foo'クラスのメンバにして、なぜあなたはいつもそのスレッドにアクセスできますか?私が持っている質問は、 'HandleEvent'関数がトリガされたときにスレッドがまだ実行中であれば、何をしたいのですか?すべての未解決のスレッドを追跡するためにデータメンバが必要な場合があります。 –

答えて

1

あなたはstd::map(または他の同様のコンテナのいずれか)を使用できます。これは明らかにあなたがあなたのニーズに合うように上記のコードを調整する必要があると思いますあなたの完全なコードではありませんので

class Foo 
{ 
    bool HandleEvents(); 
    std::map<ThingMaker*, std::thread> m_map; 
}; 

bool Foo::HandleEvents() 
{ 
    while (1) 
    { 
     switch (triggerEvent) 
     { 
      case 'h': 
      { 
       thingMaker = new ThingMaker(params); 
       m_map[thingMaker] = std::thread(function_ptr, thingMaker); 
      } break; 
      case 't': // termination event trigger 
      { 
       m_map[thingMaker].second.join(); 
       m_map.erase(thingMaker); 
       delete thingMaker; 
      } break; 
      case ...: return true; 
      default: break; 
     } 
    } 
} 

が、テンプレート内のマップのキー/値を入れ替えたり、スレッドIDを使用するともっと意味があります(例えばstd::map<std::thread::id, ThingMaker*>など)。mapは配列の繰り返し処理を避けたり、スレッドごとにjoin必ずしも必要でない場合は、フルスレッドプールの実装を実装してください。

サイドノートdetachの使用は、実際には非常に便利です。実行が終了するとすぐにスレッドを「クリーンアップ」できる(特定のリソースとハンドルを解放する)スレッド信号をカーネルに切り離す。スレッド上でdetachを呼び出すことは、(非常に短いスレッドのように)基になるスレッドハンドルにアクセスする必要がなくなるとわかったときに便利です。それは悪くも悪くもなく、利用するツール(悪名高いgotoのようなもの)だけです。

希望に応じることができます。

+0

恐ろしい答え。よく働く。 'detach'の解明もありがとう。 –

関連する問題