4

関数を同時に複数回呼び出したい。スレッドを使用して、マシンの機能を最大限に活用する関数を呼び出したいと考えています。これは 8 コアのマシンで、私の要件はマシンの CPU を 10% から 100% 以上使用することです。

私の要件は、ブーストクラスを使用することです。ブースト スレッドまたはスレッドプール ライブラリを使用してこれを達成する方法はありますか? またはそれを行う他の方法はありますか?

また、毎回異なるパラメーターを使用して (別々のスレッドで) 複数の関数を呼び出す必要がある場合、これを行う最善の方法は何ですか? [ブーストを使用するか、ブーストを使用しないか]そしてどのように?

#include <iostream>
#include <fstream>
#include <string.h>
#include <time.h>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>

using namespace std;
using boost::mutex;
using boost::thread;

int threadedAPI1( );
int threadedAPI2( );
int threadedAPI3( );
int threadedAPI4( );

int threadedAPI1( ) {
    cout << "Thread0" << endl;
}


int threadedAPI2( ) {
    cout << "Thread1" << endl;
}

int threadedAPI3( ) {
    cout << "Thread2" << endl;
}

int threadedAPI4( ) {
    cout << "Thread3" << endl;
}

int main(int argc, char* argv[]) {

    boost::threadpool::thread_pool<> threads(4);
    // start a new thread that calls the "threadLockedAPI" function
    threads.schedule(boost::bind(&threadedAPI1,0));
    threads.schedule(boost::bind(&threadedAPI2,1));
    threads.schedule(boost::bind(&threadedAPI3,2));
    threads.schedule(boost::bind(&threadedAPI4,3));
    // wait for the thread to finish
    threads.wait();

    return 0;
}

上記は機能していませんが、その理由はわかりませんか? :-(

4

3 に答える 3

6

使用する関数のドキュメントを読むことをお勧めします。James Hopkinの回答のコメントから、boost :: bindが何をするのかわからないようですが、コードをコピーして貼り付けただけです。

boost :: bindは、関数(fと呼びます)とオプションでいくつかのパラメーターを受け取り、呼び出されると、指定されたパラメーターでfを呼び出す関数を返します。

つまり、boost::bind(threadedAPI1, 0)()(引数をとらず、引数0でthreadedAPI1()を呼び出す関数を作成し、それを呼び出す)は。と同等threadedAPI1(0)です。

threadedAPI関数は実際にはパラメーターを受け取らないため、引数を渡すことはできません。これは基本的なC++です。を呼び出すことはできませんがthreadedAPI1(0)threadedAPI1()を呼び出すことはできますが、関数を呼び出すときは、(boost :: bindを介して)整数0を引数として渡そうとします。

したがって、あなたの質問に対する簡単な答えは、threadedAPI1を次のように定義することです。

int threadedAPI1(int i);

ただし、boost :: bind呼び出しを回避する1つの方法は、スレッドの起動時にfree関数ではなくファンクターを呼び出すことです。次のようなクラスを宣言します。

struct threadedAPI {
  threadedAPI(int i) : i(i) {} // A constructor taking the arguments you wish to pass to the thread, and saves them in the class instance.

  void operator()() { // The () operator is the function that is actually called when the thread starts, and because it is just a regular class member function, it can see the 'i' variable initialized by the constructor
    cout << "Thread" << i << endl; // No need to create 4 identical functions. We can just reuse this one, and pass a different `i` each time we call it.
  }
private:
  int i;
};

最後に、必要なものによっては、スレッドプールよりもプレーンスレッドの方が適している場合があります。一般に、スレッドプールは限られた数のスレッドしか実行しないため、スレッドの1つが実行を終了するまで、一部のタスクをキューに入れる場合があります。これは主に、短期間のタスクが多数ある場合を対象としています。

長時間のタスクの数が決まっている場合は、それぞれに専用のスレッドを作成するのがよいでしょう。

于 2008-12-05T18:22:53.770 に答える
4

パラメータを取らない関数にパラメータをバインドしています:

int threadedAPI1( );

boost::bind(&threadedAPI1,0)

パラメータがない場合は、関数を直接渡すだけです。

threads.schedule(&threadedAPI1)
于 2008-12-05T17:01:33.950 に答える
3

プロセッサを効率的に使用することに関心がある場合は、インテルのスレッド ビルディング ブロックhttp://www.intel.com/cd/software/products/asmo-na/eng/294797.htmを検討してください。ブーストスレッドはユーザーに制御を任せながら、マルチコアプロセッサを利用するように特別に設計されていると思います(つまり、TBBはデュアルコアと比較してクアッドコアでスレッドが異なります)。

コードに関しては、パラメーターをパラメーターにとらない関数をバインドしています。なんで?また、スケジュールからの戻りコードを確認することもできます。

于 2008-12-05T15:24:32.430 に答える