グローバル変数でスレッド間通信


【volatileキーワード】

	Fastest_PrgBar、Fastest_Posにvolatileが付けられています。
    これらは、スレッド中のループで値の変更がされることから最適化されると正常に動作しない
  可能性があることから付けられています。

  「volatileキーワードの詳細は、MSDNを参照して下さい。」

【Sample】
//スレッド用のグローバル変数
CProgressCtrl* PrgBar1;					//各種プログレスバーのハンドル番号
CProgressCtrl* PrgBar2;
CProgressCtrl* PrgBar3;
volatile CProgressCtrl* Fastest_PrgBar;	//最も進んでいるプログレスバーのハンドル番号
volatile unsigned int Fastest_Pos;		//最も進んでいるプログレスバーの位置


//プログレスバーを操作するスレッド
void barThread(CProgressCtrl* myProgbar)
{
	int i;

	//乱数発生の準備
	srand(1);

 	myProgbar->SetRange32(0,100);
	for(i = 0; i < 100; i++){
		myProgbar->SetPos(i);

		//最も進んでいるプログレスバーの情報を格納
		if(Fastest_Pos < (unsigned int)i){
			Fastest_Pos = i;
			Fastest_PrgBar = myProgbar;
		}

		Sleep(100);

		//乱数により、プログレスバーの進む速さを調節
		if(rand() > 20000)i+=5;
	}

	myProgbar->SetPos(100);
	Fastest_Pos = 100;

	//Threadを終了
	ExitThread(0);

}

//最も進んでいるプログレスバーの番号を出力
void FirstPlaceThread(CEdit* myEdit)
{
	CString strBuf;

	Fastest_Pos = 0;

	//スレッド用のグローバス変数の内容に応じて、エディット・ボックスへ値を出力
	while(Fastest_Pos < 100){
		if(Fastest_Pos != 0){
			myEdit->GetWindowText(strBuf);
			if((Fastest_PrgBar == PrgBar1) && (strBuf != "@")){
				myEdit->SetWindowText("@");
			}
			else if((Fastest_PrgBar == PrgBar2) && (strBuf != "A")){
				myEdit->SetWindowText("A");
			}
			else if((Fastest_PrgBar == PrgBar3) && (strBuf != "B")){
				myEdit->SetWindowText("B");
			}
		}
		else{
			myEdit->SetWindowText("");
		}
	}

	//Threadを終了
	ExitThread(0);

}

//プログレスバー@操作用スレッド実行ボタン
void CThreadsapDlg::OnStart1Button() 
{
	HANDLE hThread;
	DWORD threadID;

	//操作対象のプログレスバーを取得
	PrgBar1 = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);

	//スレッドの実行
	hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)barThread,
					(VOID *)PrgBar1, 0, &threadID);


}

//プログレスバーA操作用スレッド実行ボタン
void CThreadsapDlg::OnStart2Button() 
{
	HANDLE hThread;
	DWORD threadID;

	//操作対象のプログレスバーを取得
	PrgBar2 = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS2);

	//スレッドの実行
	hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)barThread,
					(VOID *)PrgBar2, 0, &threadID);	
}

//プログレスバーB操作用スレッド実行ボタン
void CThreadsapDlg::OnStart3Button() 
{
	HANDLE hThread;
	DWORD threadID;

	//操作対象のプログレスバーを取得
	PrgBar3 = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS3);

	//スレッドの実行
	hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)barThread,
					(VOID *)PrgBar3, 0, &threadID);	
}


//最も進んでいるプログレスバーを判定する
void CThreadsapDlg::OnButton4() 
{
	HANDLE hThread;
	DWORD threadID;

	//1位プログレスバー番号出力エディット・ボックスを取得
	CEdit* myEdit = (CEdit*)GetDlgItem(IDC_EDIT1);

	//スレッドの実行
	hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)FirstPlaceThread,
					(VOID *)myEdit, 0, &threadID);
}