FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  1. --/--/--(--) --:--:--|
  2. スポンサー広告

マルチスレッドプログラミング サンプル

マルチスレッドの勉強の為に作成したサンプルプログラムです。

エラー処理なにそれ?おいしいの?

状態のソースです。それを考慮して参考にして下さいませ。
VC++2008ExpressEditionで作成・動作確認しました。
続きへ行ってください。
長い…。

注1)説明文、文字化けしてるようです。

サンプルソース
#include<stdio.h>
#include<windows.h>
#include<process.h>

#define THREAD_COUNT 5

unsigned __stdcall SecondThread(LPVOID pParam)
{
int *id=(int *)pParam,l=0;

Sleep(50);
for(int n=1;n<=10;n++){
printf("ID%d_Thread -> %02d\n",*id,n);
Sleep(500);
}
_endthreadex(0);

return 0;
}

int main(void)
{
HANDLE hThread[THREAD_COUNT];
UINT ID[THREAD_COUNT]={0,};
int n=0,nParam[THREAD_COUNT];

for(n=0;n<THREAD_COUNT;n++){
nParam[n]=n;
hThread[n]=(HANDLE)_beginthreadex(NULL,0,&SecondThread,(LPVOID)&nParam[n],CREATE_SUSPENDED,&ID[n]);
if(hThread[n]==NULL)exit(1);
}

for(n=0;n<THREAD_COUNT;n++)ResumeThread(hThread[n]);

printf("Start for Multi thread.\n\n");

for(n=1;n<=10;n++){
printf("Main_Thread -> %02d\n",n);
Sleep(500);
}

WaitForMultipleObjects(THREAD_COUNT,hThread,TRUE,INFINITE);

for(n=0;n<THREAD_COUNT;n++)CloseHandle(hThread[n]);

printf("\nEnd for Multi thread.\nPlease any key.\n");
getchar();
return 0;
}


実行結果
Start for Multi thread.

Main_Thread -> 01
ID3_Thread -> 01
ID2_Thread -> 01
ID1_Thread -> 01
ID0_Thread -> 01
ID4_Thread -> 01
Main_Thread -> 02
ID0_Thread -> 02
ID1_Thread -> 02
ID2_Thread -> 02
ID3_Thread -> 02
ID4_Thread -> 02
Main_Thread -> 03
ID3_Thread -> 03
ID2_Thread -> 03
ID1_Thread -> 03
ID0_Thread -> 03
ID4_Thread -> 03
Main_Thread -> 04
ID0_Thread -> 04
ID1_Thread -> 04
ID2_Thread -> 04
ID3_Thread -> 04
ID4_Thread -> 04
Main_Thread -> 05
ID4_Thread -> 05
ID3_Thread -> 05
ID2_Thread -> 05
ID1_Thread -> 05
ID0_Thread -> 05
Main_Thread -> 06
ID1_Thread -> 06
ID2_Thread -> 06
ID3_Thread -> 06
ID4_Thread -> 06
ID0_Thread -> 06
Main_Thread -> 07
ID4_Thread -> 07
ID3_Thread -> 07
ID2_Thread -> 07
ID1_Thread -> 07
ID0_Thread -> 07
Main_Thread -> 08
ID1_Thread -> 08
ID2_Thread -> 08
ID3_Thread -> 08
ID4_Thread -> 08
ID0_Thread -> 08
Main_Thread -> 09
ID4_Thread -> 09
ID3_Thread -> 09
ID2_Thread -> 09
ID1_Thread -> 09
ID0_Thread -> 09
Main_Thread -> 10
ID1_Thread -> 10
ID2_Thread -> 10
ID3_Thread -> 10
ID4_Thread -> 10
ID0_Thread -> 10

End for Multi thread.
Please any key.

ID?_Threadの番号の順序が変則的なのに気付きましたか?
それがマルチスレッドの特徴です。
もちろん同期させることも可能です。
実行結果は実行毎に変化します。

#define THREAD_COUNT 5

の5が作成するスレッドの数です。
変更してみて下さい。0とかマイナスとか文字とかはやめた方がいいですよ。


・説明

_beginthreadex関数
・新規スレッドを作成します。
uintptr_t _beginthreadex( 
void *security, //SECURITY_ATTRIBUTES 構造体へのポインタ
unsigned stack_size, //スレッドのスタックサイズ
unsigned ( *start_address )( void * ),//スレッドルーチンのアドレス
void *arglist, //スレッドルーチンに渡す引数のポインタ
unsigned initflag, //スレッドの初期状態
unsigned *thrdaddr //スレッドの識別子を格納するポインタ
);

第一引数 NULLでOKです。普段使用しない。
第二引数 0でOKです。自動設定になる。あれ?プライマリスレッドの設定を継承するんだっけ?
第三引数 サンプルだとSecondThread関数のアドレスを渡してます。
そのアドレスの形式は固定です。
unsigned __stdcall 関数名(void * 引数名)
__stdcallはWINAPIなどでも同じです。
第四引数 スレッドへ渡したい引数のポインタを指定する。
サンプルではスレッドの番号を引数にしてます。
第五引数 スレッド作成直後に開始するか一時停止させるかを指定します。
スレッド作成直後に開始させる場合0。
一時停止の場合CREATE_SUSPENDEDを指定します。
再開はResumeThread関数で行います。
第六引数 スレッド識別子を格納する32bitの変数へのポインタを指定します。
このスレッド識別子でスレッドを操作できます。
サンプルでは格納はしてますが使用してません。

戻り値はスレッドハンドルと呼ばれるスレッド識別子です。
型キャストして格納します。
エラー時には、NULLが返ります。

ResumeThread関数
・スレッドを開始します。
DWORD ResumeThread(
HANDLE hThread // スレッドのハンドル
);

引数には_beginthreadex関数の戻り値を指定。

戻り値は、成功するとこの関数を呼び出す前のサスペンドカウントが返ります。
エラーは-1です。

WaitForMultipleObjects関数
・指定されたハンドルが、指定された待機オプションを満たすまで待機します。
DWORD WaitForMultipleObjects(
DWORD nCount, // 配列内のハンドルの数
CONST HANDLE *lpHandles, // オブジェクトハンドルからなる配列
BOOL fWaitAll, // 待機オプション
DWORD dwMilliseconds // タイムアウト時間
);

第一引数 ハンドルの数を指定。サンプルは作成したスレッドの数です。
第二引数 ハンドルを格納した配列のアドレス。
サンプルはスレッドハンドルを格納した配列の先頭アドレスを指定。
第三引数 FALSEで指定ハンドルの内一つでもシグナル状態になったとき、待機から脱します。
TRUEで指定ハンドル全てがシグナル状態になったとき、待機から脱します。
サンプルでは、スレッドが終了した場合がシグナル状態です。
第四引数 文字どうりです。単位は[ms]。INFINITEで待機オプションを満たすまでいつまでも待機します。

戻り値は、
タイムアウトの時、WAIT_TIMEOUT
失敗は、WAIT_FAILEDです。
ほかは成功。

CloseHandle関数
・開いたハンドルを閉じる。
BOOL CloseHandle(
HANDLE hObject // オブジェクトのハンドル
);

引数にはハンドルを指定。サンプルはスレッドのハンドルです。

戻り値
成功は!0(0以外、TRUEとも言う)
失敗は0

_endthreadex関数
・_beginthreadex()で作成したスレッドを終了する。
void _endthreadex( 
unsigned retval //スレッド終了コード
);
引数には終了コードを指定します。
デバッカの出力にスレッド終了時のコードが表示されるのです。
システムに返す値じゃない…………と思う。
デバックするとき活用しましょう。

tema:プログラミング - Genre:コンピュータ

  1. 2010/09/19(日) 21:02:45|
  2. プログラミング
  3. | Track back:0
  4. | Comment:5

Comment

No.248

俺もC++出来るけどねぇ。
どっちかというと、HTMLかな。
て言うか、HTMLの方が出来る
  1. 2010/09/23(木) 00:24:03 |
  2. URL |
  3. エネミーライン #JalddpaA
  4. [ Edit]

No.247

>K・Gさん

独学と言ってもインターネットが普及した今。
独学は独学と言えないかもしれません。
特に「猫でもわかるプログラミング」というサイトにはかなりお世話になってます。

>様々なユーザーに提供するのって大変です。

同感です。
ネットワークプログラミングだと様々な相手との通信を想定しなくてはならないので、なるべく依存性の無いコードを書かないといけない。
VC++に依存してる時点でダメなんですがね。(^^;
  1. 2010/09/21(火) 14:11:21 |
  2. URL |
  3. BLACK #-
  4. [ Edit]

No.246

お。マルチスレッドですね。
私もゲーム用のプログラムに使用しています。これがないといろいろ困りますからね。友人がcorei7のコア全部使ったスレッド管理してましたが、最新のPCでしか動かないアプリとかどうなのよって教員に突っ込みいれられてましたね(^^;
様々なユーザーに提供するのって大変です。

しかし独学でここまでできるなんて……。御見それしました。
  1. 2010/09/21(火) 12:49:04 |
  2. URL |
  3. K・G #L1ch7n1I
  4. [ Edit]

No.245

>VARRELさん

そうですね。
core i7なら最大8スレッド並列処理できますから。
例えば、1スレッドで音楽をMP3にエンコードする場合。
同時に8曲までエンコードできます。
100曲一気に変換したい。
なんて場合は、理論上ソロコアCPUに比べ8倍効率がいいコトになりますね。

私も欲しいです。
PCでPS2がやりたい。
結構高性能じゃないとPS2はPCでプレイ出来ない。
  1. 2010/09/20(月) 19:26:36 |
  2. URL |
  3. BLACK #-
  4. [ Edit]

No.244

これが使えるとなるとAMDよりもIntelのcoreI7のほうが欲しくなってくる
  1. 2010/09/20(月) 00:48:18 |
  2. URL |
  3. VARREL #-
  4. [ Edit]

Post a comment

Only display to administrator.

Track back

Track Back URL
Track Back to this post(FC2 blog user)