○SDKにてスレッドの使い方


■コンパイラの設定


◇VC.net 
	[表示] メニューの [プロパティ ページ] をクリックします。[プロパティ ページ] ダイアログ ボックスで	、[C/C++] フォルダをクリックします。[コード生成] ページを選択します。[ランタイム ライブラリ] ボッ	クスの [マルチスレッド] を選択します。[OK] をクリックします。 
◇VC6
	プロジェクト→設定→C/C++→コード生成→マルチスレッド


■スレッド生成関数の説明

	uintptr_t _beginthread( 
		void( __cdecl *start_address )( void * ),
		unsigned stack_size,
		void *arglist 
	);



	start_address 
	新規スレッドの実行を起動するルーチンの開始アドレス。 
	stack_size 
	新規スレッドのスタック サイズまたは 0。 
	arglist 
	新規スレッドに渡される引数リストまたは NULL。



■スレッド生成の実際


#include <process.h> //追加します

void Thread(char*str){ //適当な関数をスレッドにて回します
	while(true){
		Sleep(100);
		OutputDebugString(str);//デバッグ出力
	}
}

_beginthread((void(*)(void*))Thread,0,"test");//スレッドのスタート
_beginthread((void(*)(void*))Thread,0,"str");//同じ関数を複数のスレッドで回せます



■クリティカルセッション(シンクロナイズメソッド)の実現

HANDLE     hIOMutex = CreateMutex (NULL, FALSE, NULL);
//↑グローバルで宣言
void Sincronaized(void){
     WaitForSingleObject( hIOMutex, INFINITE );
     //処理内容
     ReleaseMutex( hIOMutex);
}


■入出力完了ポートを利用したスレッドプール

#include <stdio.h>
#include <conio.h>
#include <process.h>
#include <windows.h>

//プールするスレッド数
#define THREAD_POOL 10

typedef struct _MYOVERLAPPED {
	DWORD  Internal; 
	DWORD  InternalHigh; 
	DWORD  Offset; 
	DWORD  OffsetHigh; 
	HANDLE hEvent;
	void*ptr;
} MYOVERLAPPED,*LPMYOVERLAPPED;

HANDLE CompPort;

unsigned __stdcall thread(void*obj){
	LPMYOVERLAPPED myol=NULL;
	DWORD numberOfBytesTransferred=0;
	ULONG completionKey=0;
	
	while(1){
		//実行が値を受け取るまでブロックされる
		BOOL ret = GetQueuedCompletionStatus(
			CompPort,
			&numberOfBytesTransferred,
			&completionKey,
			(LPOVERLAPPED*)&myol,
			INFINITE);
		
		if(ret){
			char c=(char)myol->ptr;
			printf("%d:%c\n",(int)obj,c);
			free(myol);
			Sleep(1000);
		}
	}
	return 0;
}


int main(){
	CompPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,THREAD_POOL);

	//ワーカースレッドを作成する
	for(int i=0;i<THREAD_POOL;i++){
		HANDLE hd=(HANDLE)_beginthreadex(NULL,0,thread,(void*)i,0,NULL);
		CloseHandle(hd);
	}

	while(1){
		//キーボードが押されたときにスレッドを動作させる
		if(_kbhit()){
			LPMYOVERLAPPED st=(LPMYOVERLAPPED)malloc(sizeof(MYOVERLAPPED));
			st->ptr=(void*)_getch();
			//スレッドに値を渡して動作させる
			PostQueuedCompletionStatus(CompPort,0,0,(LPOVERLAPPED)st);
		}
	}
	return 0;
}





▲トップページ > Windows と C++