2011-01-22 21 views
3

に私は別のスレッドで異なるパラメータで一つの機能を実行したい:は、マルチスレッドでは、C++

int threads = 3; 
int par1[] = {1, 2, 3}; 
int par2[] = {4, 5, 6}; 
for (int i=0; i<threads; i++){ 
    //new_thread function(par1[i], par2[i]); 
} 

私はスレッドについて何も知りません。私はWindows API(他のライブラリを使うことはできません)をしようとしましたが、うまくいきません。これをどのように実装すればよいですか?そして、プログラミングの時間の不明な数のスレッドを開始することは可能です(スレッドを動的に作成する)?この例では

答えて

11

Windows用の1つのサンプル例、

#include <Windows.h> 

struct thread_data 
{ 
int m_id; 
thread_data(int id) : m_id(id) {} 
}; 
DWORD WINAPI thread_func(LPVOID lpParameter) 
{ 
thread_data *td = (thread_data*)lpParameter; 
cout << "thread with id = " << td->m_id << endl; 
return 0; 
} 
int main() 
{ 
for (int i=0; i< 10; i++) 
{ 
    CreateThread(NULL, 0, thread_func, new thread_data(i) , 0, 0); 
} 
} 

、各スレッドは、スレッド関数thread_func()に引数として渡される、すなわちタイプthread_dataの異なるデータを、取得します。

Windows上でスレッドを作成する方法を知っているこれらを読む:

http://msdn.microsoft.com/en-us/library/ms682516(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms682453(v=vs.85).aspx


また、あなたにもこの提案を好むことがあります。

Better design : define a reusable class!

+3

+1たとえば、はるかに助けて!私はOPがMSDNで 'CreateThread'を見つけることができると確信しています。 –

+0

エラー "型の引数" DWORD(__stdcall accel :: *)(LPVOID lpParameter)の引数が "LPTHREAD_START_ROUTINE"型のパラメータと互換性がありません。関数がクラスにあるためですか? – gemexas

+1

@gemexas:はい。その関数は 'static'です。このトピックを参照してください:http://stackoverflow.com/questions/4666635/run-threads-of-class-member-function-in-c/4666666 – Nawaz

3

をあなたがこれを機能させるには、いくつかのことをする必要があります。すべてのウィンドウのスレッド関数の最初にこの署名を取る:あなたのスレッド関数に引数を渡す方法がLPVOID経由であることを

HANDLE WINAPI CreateThread(
    __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, 
    __in  SIZE_T dwStackSize, 
    __in  LPTHREAD_START_ROUTINE lpStartAddress, 
    __in_opt LPVOID lpParameter, 
    __in  DWORD dwCreationFlags, 
    __out_opt LPDWORD lpThreadId 
); 

注:

DWORD WINAPI ThreadFunction(LPVOID args) 

スレッドのスタートアップ・ルーチンは、この機能です。つまり、par1par2を保持する構造を作成する必要があります。この構造体へのポインタを渡し、スレッドルーチンで内容を引き出します。

0

Windowsでは、CreateThreadを呼び出してスレッドを作成します。例はhereです。

はい、動的にスレッドを作成できます。

"スレッド関数"が呼び出されると(スレッドが開始されたことを意味します)、CreateThreadを呼び出すときに渡した渡されたパラメータを使用します。
"スレッド関数"では、 "LPVOID lpParam"です。あなたはあなたのタイプにキャストする必要があります。それがスレッドに渡す必要がある2つのオブジェクトの場合は、適切なメンバで独自のカスタム構造体/クラスを作成し、後で使用できるようにCreateThreadを呼び出すときにそのインスタンスを渡します。非常にストレートです。

0

OpenMPsupported in Visual studioなので、なぜそれを使用しないのですか?手作業で独自のスレッドを管理するよりもはるかに簡単で、移植性が高く、与えた例はほとんど完璧です。ウィキペディアには理由がありますintroduction to the concepts of OpenMP。あなたの例では

簡単な(そして少しナイーブ - 通常あなたは明示的にスレッド数を言っていない、あなたが作業単位の数を言う)のコードは次のようになりますに渡され、適切なオプションを使用すると

int threads = 3; 
int par1[] = {1, 2, 3}; 
int par2[] = {4, 5, 6}; 
#pragma omp parallel for 
for (int i=0; i<threads; i++){ 
    function(par1[i], par2[i]); 
} 

OpenMPを有効にするコンパイラ。このオプションがなければ、まだコンパイルされ、シリアルプログラムとして実行されます。

4

スレッドについては何も分かりません。

これは問題です。スレッドは、少なくともの理論的背景なしの実験が通常大惨事で終わる領域の1つです。スレッディングで間違っていることが多くありますが、多くの場合、多くの場合は後になります。

私は、マルチスレッドに関する書籍を入手するか、オンラインでいくつかの記事を読むことをお勧めします。

効率のためにマルチスレッドを使用したい場合は、Herb Sutter’s columnが適している可能性があります。そして、Blaise Barneyの素晴らしいIntroduction to Parallel Computingがあります。

1

boost::thread_groupの使用をお勧めしますか?

boost::thread_group g; 
int threads = 3; 
int par1[] = {1, 2, 3}; 
int par2[] = {4, 5, 6}; 
for (int i=0; i<threads; i++){ 
    g.create_thread(/*function*/); 
    //new_thread function(par1[i], par2[i]); 
} 
g.join_all(); 
関連する問題