2

私の質問を直接する前に、私の問題の性質を説明します。C++/OpenGL と GLFW ライブラリを使用して 2D シミュレーションをコーディングしています。そして、たくさんのスレッドを適切に管理する必要があります。GLFW では、関数を呼び出す必要があります: thread = glfwCreateThread(ThreadFunc, NULL); (最初のパラメーターはスレッドを実行する関数で、2 番目のパラメーターはこの関数のパラメーターを表します)。そして glfwCreateThread は毎回呼び出さなければなりません! (つまり、各サイクルで)。この作業方法は、メインループスコープの外にスレッドを作成する必要があるため、コードを構築する方法を壊してしまうため、実際には役に立ちません。そこで、次のプロトタイプを持つ ThreadManager クラスを作成しています。

class ThreadManager {

  public:
         ThreadManager();
         void AddThread(void*, void GLFWCALL (*pt2Func)(void*)); 
         void DeleteThread(void GLFWCALL (*pt2Func)(void*));
         void ExecuteAllThreads();

  private:
         vector<void GLFWCALL (*pt2Func)(void*)> list_functions;
         // some attributs             


};

たとえば、特定のスレッドを追加したい場合は、特定のパラメーターと特定の関数を指定して AddThread を呼び出すだけです。目標は、次のように呼び出せるようにすることです。メインループスコープ内。しかし、これには次のようなものが必要です:

void ExecuteAllThreads() {

      vector<void GLFWCALL (*pt2Func)(void*)>::const_iterator iter_end = list_functions.end();
      for(vector<void GLFWCALL (*pt2Func)(void*)>::const_iterator iter = list_functions.begin();
      iter != iter_end; ++iter) {

           thread = glfwCreateThread(&(iter*), param);
      }
}

AddThread 内では、pt2Func によって参照される関数をベクトルに追加する必要があります: list_functions。

さて、これは私がやりたいことの一般的な考えです..それは正しい方法ですか?もっと良いアイデアがありますか?どうやってこれを行うのですか?(つまり、問題は構文です。これを行う方法がわかりません)。

ありがとうございました !

4

4 に答える 4

3

各シミュレーション サイクルでスレッドを作成する必要がありますか? それは疑わしいですね。スレッドを一度作成して再利用します。

スレッドの作成は安価な操作ではありません。すべての反復ステップでそれを行いたくないことは間違いありません。

可能であれば、タイプ セーフやその他の便利な機能を提供するために、代わりにスレッドに Boost.Thread を使用することをお勧めします。スレッド化は、型の安全性を捨てたり、プリミティブな C API を操作したりすることなく、十分に複雑です。

とはいえ、面倒ですが、あなたが求めていることは可能です。まず、関数の引数も保存する必要があるため、クラスは次のようになります。

class ThreadManager {

  public:
         typedef void GLFWCALL (*pt2Func)(void*); // Just a convenience typedef
         typedef std::vector<std::pair<pt2Func, void*> > func_vector;
         ThreadManager();
         void AddThread(void*, pt2Func); 
         void DeleteThread(pt2Func);
         void ExecuteAllThreads();

  private:
         func_vector list_functions;
};

そして、ExecuteAllThreads:

void ExecuteAllThreads() {

      func_vector::const_iterator iter_end = list_functions.end();

      for(func_vector::const_iterator iter = list_functions.begin();
      iter != iter_end; ++iter) {

           thread = glfwCreateThread(iter->first, iter->second);
      }
}

もちろん、AddThread 内では、関数ポインタと引数のペアをベクトルに追加する必要があります。

Boost.Thread は、スレッドがファンクター (状態を保持できるため、明示的な引数を必要としない) であると想定しているため、このほとんどをよりクリーンに解決することに注意してください。

スレッド関数は次のように定義できます。

class MyThread {
  MyThread(/* Pass whatever arguments you want in the constructor, and store them in the object as members */);

  void operator()() {
    // The actual thread function
  }

};

また、operator() はパラメーターを取らないため、スレッドの開始が非常に簡単になります。

于 2009-04-24T14:49:53.667 に答える
2

boost::function を使用してそれらを保存しようとするのはどうですか?

それらは実際のオブジェクトのように動作しますが、実際には単純なファンクターであるため、特定の関数をシミュレートできます。

于 2009-04-24T14:48:07.743 に答える
2

ブースト スレッドとスレッド グループを検討する

于 2009-04-24T15:02:01.703 に答える
1

私はあなたが使用しているスレッドシステムに慣れていません。我慢してください。

スレッド識別子のリストを維持するべきではありませんか?

 class ThreadManager {
     private:
       vector<thread_id_t> mThreads;
     // ...
 };

そして、ExecuteAllThreadsあなたは次のようにします:

 for_each(mThreads.begin(), mThreads.end(), bind(some_fun, _1));

(Boost Lambda バインドおよびプレースホルダー引数を使用) ここで、some_fun はすべてのスレッドに対して呼び出す関数です。

それとも、特定のスレッドに対して一連の関数を呼び出したいですか?

于 2009-04-24T14:50:35.117 に答える