グローバル変数でスレッド間通信
【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);
}