スポンサーリンク

| キーワード:

極力Windows+C言語でスレッドを使うサンプル

あれだ。サンプル作れといわれたので即興で書きました。仕事は普段CLIなんで個人的には使う機会すくないです。

 

#include <stdio.h>
#include <process.h> //スレッドを使用するために読み込む
#include <windows.h> //HANDLE型のために読み込む
//スレッドのサンプル(Windows,C言語, beginthread版)
#define COUNT 40
//スレッドとなる関数  戻り値void , 引数void*、呼び出し規約__stdcall指定の関数である必要がある
unsigned __stdcall Thread_Function(void* p);
//スレッドに渡す引数を束ねた構造体
struct arg_forThread{
HANDLE hMutex;
int uid;
int start;
int end;
int *pInteger;
double* pDouble;
int *pprogress;
};
////////////////////////////////////////////////////////
//エントリポイント
////////////////////////////////////////////////////////
int main(int argc,char* argv[]){
//処理内容
//Integer配列の中身を1/2した結果をDouble配列に格納します。
int Integer[COUNT]; //元データが入った配列
double Double[COUNT]; //結果を格納する配列
HANDLE hMutex; //排他処理用の変数
HANDLE hThread[2];
int progress = 0;
for(int i = 0; i < COUNT; i++){
		Integer[i] = i;
}
//スレッド開始の前に排他処理の設定
	hMutex = CreateMutex(NULL,FALSE,NULL);
//引数を設定
	arg_forThread arg1 = {
		hMutex,
0,
0,
		COUNT/2-1,
		Integer,
		Double,
&progress
	};
//引数を設定
	arg_forThread arg2 = {
		hMutex,
1,
		COUNT/2,
		COUNT-1,
		Integer,
		Double,
&progress
	};
//スレッド開始
//スレッドどなる関数へは引数を一つしか渡せないため、void*へキャストした構造体のインスタンスへのポインタを渡す
	hThread[0] = (HANDLE)_beginthreadex(
NULL,
0,
		Thread_Function , //スレッドとして走らせる関数を指定
(void*)&arg1, //(Thread_Function)が受け取る引数
0, //すぐ実行
NULL
);

	hThread[1] = (HANDLE)_beginthreadex(
NULL,
0,
		Thread_Function , //スレッドとして走らせる関数を指定
(void*)&arg2, //(Thread_Function)が受け取る引数
0, //すぐ実行
NULL
);
//両方のスレッドが終了するまで待ちます。
//スレッドがすべて終了するまでフリーズすることになります。
WaitForMultipleObjects(2,hThread,TRUE,INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hMutex);
getchar(); //結果をゆっくり見るためのgetchar
return 0;
}
unsigned __stdcall Thread_Function(void* p){
//引数を受け取る
struct arg_forThread* parg = (arg_forThread*)(p);
HANDLE hMutex = parg->hMutex;
int uid = parg->uid;
int start = parg->start;
int end = parg->end;
int* pInteger = parg->pInteger;
double* pDouble = parg->pDouble;
int* pprogress = parg->pprogress;
for(int i = start; i <= end; i++){
Sleep(uid?7:3); //重い処理を入れないと結果がわかりにくい

		pDouble[i] = pInteger[i]/2.0; //処理本体
//Mutexは同一領域に書き込まない場合は必要ないので、呼出元でstart-endがダブらないようにしているpDoubleに対してはかける必要がない
//pprogressが指す先のメモリは同時に変更される可能性があるので、排他処理をしないといけない
WaitForSingleObject( hMutex , INFINITE ); //他のスレッドから参照できなくする
(*pprogress)++;
printf("%s\t%.2lf%%\t%d %lf %d\n",uid?"*":"***",(double)(*pprogress)/COUNT*100,i, pDouble[i],pInteger[i]);
ReleaseMutex( hMutex );
}
return 0;
}

 

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: