2009-05-15 28 views
0

新しいスレッドで「実行」関数を呼び出そうとしています。今、私はこのコードを実際には新しいスレッドで "Run"を実行しないopenMPを使用しています。注:私はOpenMPを使用して助けを求めていません。このコードはちょうど簡単な修正でした。私はこれについて行くのCreateThread()メソッドを好むだろう。継承を使用したマルチスレッド化(C++)

vector<ICommand*>* commands; 
string strInput; 
// For each command... 
for(vector<ICommand*>::iterator i = commands->begin(); i != commands->end(); ++i) 
{ 
    // ...if the current command we're examining is valid... 
    if((*i)->ContainsCommand(strInput)) 
    { 
     // ...run it in a new thread and don't let ZChatInput handle it normally... 
     #pragma omp sections nowait 
     { 
     #pragma omp section 
      (*i)->Run(strInput); 
     #pragma omp section 
      bRet = false; 
     } 

     // ...and don't check any more commands. 
     break; 
    } 

} 

これは、標準とSTLだけを使用してどのように行われますか?もちろん、私は動作する方法を探しています:)

答えて

0

だから、私はMSDNのドキュメントをダブルチェックした後にそれを理解しました。あなたが興味を持っている場合は、どうやってやったのですか。

static vector<ICommand*>* commands; 
// This is what we pass to CommandOnThread. 
struct CommandParameter 
{ 
    string strInput; 
    ICommand* command; 
}; 

int CommandOnThread(CommandParameter* cp) 
{ 
    cp->command->Run(cp->strInput); 
    delete cp; 

    return 0; 
} 

void foo() 
{ 
    string strInput; 
    ... 
    // For each command... 
    for(vector<ICommand*>::iterator i = commands->begin(); i != commands->end(); ++i) 
    { 
     // ...if the current command we're examining is valid... 
     if((*i)->ContainsCommand(strInput)) 
     { 
      // Put the CP on the stack. 
      CommandParameter* temp = new CommandParameter; 
      if(temp == NULL) 
      { 
       Print("Out of memory!"); 
       bRet = false; 
       break; 
      } 

      // ...set up the parameters to createthread... 
      temp->strInput = strInput; 
      temp->command = *i; 

      // ...run it in a new thread... 
      CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CommandOnThread, temp, NULL, NULL); 

      // ...and don't check any more commands. 
      bRet = false; 
      break; 
     } 
    } 
} 
3

Boost.Threadの使い方はどうですか?

if((*i)->ContainsCommand(strInput)) 
{ 
    boost::thread t(boost::bind(&ICommand::Run, *i)); 
} 

これは、分離スレッドで "実行"を実行します。 (これはテストしていないことに注意してください)

+0

いいえ、ごめんなさい。私は第三者図書館から恥ずかしがるようにしています。この機能がVS2010にある場合は、試してみます。しかしそれまでは、私が探しているものではありません。また、strInputをパラメータとして渡すのを忘れてしまった。 –

+2

ブーストの問題は何ですか?これはstlとほぼ同じように標準です。多くのブーストライブラリが新しい標準に入り、ブーストスレッドが新しい標準になると私は感心しません(私はスレッドの新しい標準があることを知っていますが、それらがブーストスレッドに似ているかどうかはわかりませんモデル) –

+0

C++ 0xにはboost.threadに似たスレッド機能があります。参照してくださいhttp://en.wikipedia.org/wiki/C%2B%2B0x#Threading_facilities –

1

本当にコマンドごとにスレッドを作成しますか?スレッドの作成は高価です。 この部分が非同期である必要がある場合 - 同期化されたキューを作成するには、事前に生成されたスレッド数(スケーラビリティ)をキューでブロックし、 。

 
// setup 
sync_queue wq; // that would be protected by mutex and a conditional var or two 
for (i = 0; i < parallel_factor; ++i) start_thread(th_func, wq); 
... 

// your loop body : 
    ... 
    if (valid_input) q.put(item); 
    ... 

// thread function 
void th_func(sync_queue& q) 
{ 
    work_item* pwi; 
    while ((pwi = q.get())) do_it(pwi); 
} 

は理にかなって:

あなたのコメントに答えますか?

+0

コマンドごとにスレッドを作成しているわけではありません。入力が有効な場合にのみスレッドを作成し、それ以上は作成しません。そうでなければ、それは本当に辛いほど遅くなるので、非同期でなければならない(MUST)。私はあなたの実装戦略を理解していません。いくつかの擬似コードの例を表示できますか? –

+0

それはします...しかし、それは単純なスレッド作成のための多くの仕事のようです... CreateThreadまたは他のWinAPIでより良い方法になるはずです。 –

+0

有効な入力ごとにRun()を呼び出しますか?その後、スレッドが事前に起動されていることを確認します。それ以外の場合は、シングルスレッドより遅いことがわかります。そして、はい、糸を乱すことはたくさんの作業です。 –

2

このような?このため

vector<ICommand*>* commands; 
string strInput; 

void CommandOnThread(void* command) 
{ 
    (ICommand*)command->Run(); 
} 

// For each command... 
for(vector<ICommand*>::iterator i = commands->begin(); i != commands->end(); ++i) 
{ 
    // ...if the current command we're examining is valid... 
    if((*i)->ContainsCommand(strInput)) 
    { 
     //Attach the input to the command 
     (*i)->AttachInput(strInput); 
     _beginthread(CommandOnThread, 0, *i); 
     break; 
    } 
} 

あなたはわずか2つのステップでコマンド入力を渡すためのコマンド・インタフェースを変更する必要があります:最初のコマンドオブジェクトに入力を保存し、呼び出すhttp://msdn.microsoft.com/en-us/library/kdzttdcb(VS.80).aspx

+0

私が提供したコードのコンテキストで私を見せてもらえますか?ブーストの例に似た –

+0

は、あなたの関数へのポインタをパラメータとして使用します。 _beginthreadとCreateThreadはマルチスレッドのMS関数です – DaClown

+0

int h =(HANDLE)_beginthreadex(NULL、0、(* i) - >実行、&strInput、0、NULL); 正確にはわからず、実行は_stdcall関数でなければなりません。これはwin32のAPIです – ryansstack

2

あなたはこのような何かを試すことができます引数なしでRun()を実行します。あなたが似ているのが好きなら、_beginthreadをCreateThreadに置き換えることができます。

明確にする:_beginthread(またはCreateThread)の関数パラメータとしてインスタンスメソッドを使用することはできません。上記の解決策は、オブジェクト(コマンド)を関数に渡し、そのインスタンスメソッド(実行)を呼び出すことです。しかし、この場合、スレッド関数に余分な引数を渡すことはできません。したがって、引数をインスタンスメソッドに渡すことはできません。このための最も簡単な解決策は、スレッド関数に渡す前に、引数をインスタンスに何らかの形で添付することです。

こちらがお役に立てば幸いです。もちろん、Commandクラスのインタフェースと実装を変更できない場合、この解決策は不可能です。

+0

"AttachInput"はどこに定義されていますか?また、コマンド - >実行()にパラメータを渡していません。 –

+0

自分で定義する必要があります。 1つの引数はスレッド関数に渡すことができ、コマンドオブジェクトを渡すためにすでに使用されています。 –

関連する問題