【VC++】簡単なマルチスレッド その2
<機能>
(1)AfxBeginThreadを使用したマルチスレッドサンプルです
(2)セマフォ(CSemaphoreクラス)を使って排他制御します
(3)public変数 count を5スレッドからカウントアップします
※1スレッドあたり100カウントアップするためcount=500となります
(排他制御(CSingleLock::Lock/Unlock)がないとcount<500)
<イメージ>
排他制御実装前の結果は、100カウントアップするスレッドを5つ起動してcount=500になりません
セマフォを使ってcountをいずれか1スレッドからしか使えないように排他制御(CSingleLock::Lock/Unlock)するとcount=500となりました
<動作検証&開発環境>
Visual Studio Community 2017
Visual Studio Community 2017
<使い方>
1.ダイアログベースでThreadSample2プロジェクトを作成
2.エディットボックスとボタンを配置
IDC_EDIT1/IDC_EDIT2:ReadOnly=TRUE
3.コントロール変数を追加
IDC_EDIT1 : m_EdtCount(種類EDIT/カテゴリControl)
IDC_EDIT2 : m_EdtThread(種類EDIT/カテゴリControl)
4.ソース追加
ThreadSample2Dlg.h
class CThreadSample2Dlg : public CDialogEx
{
{
//~~省略~~
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton1();
int count;
int threadno;
CWinThread *mythread;
CEdit m_EdtCount;
CEdit m_EdtThread;
//セマフォオブジェクト(スレッド間のロックに使用)
CSemaphore m_cSmp;
};
int threadno;
CWinThread *mythread;
CEdit m_EdtCount;
CEdit m_EdtThread;
//セマフォオブジェクト(スレッド間のロックに使用)
CSemaphore m_cSmp;
};
ThreadSample2Dlg.cpp
//プロトタイプ宣言
UINT __cdecl CountUpThread(LPVOID p);
UINT __cdecl CountUpThread(LPVOID p);
BOOL CThreadSample2Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
{
CDialogEx::OnInitDialog();
// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
// Framework は、この設定を自動的に行います。
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
// Framework は、この設定を自動的に行います。
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
//エディットボックスの初期表示
m_EdtCount.SetWindowTextW(L"0");
m_EdtThread.SetWindowTextW(L"0");
m_EdtCount.SetWindowTextW(L"0");
m_EdtThread.SetWindowTextW(L"0");
return TRUE;
}
}
/*************************************************
関数名 OnBnClickedButton1
機能 セマフォで同期 ボタン押下イベント
*************************************************/
void CThreadSample2Dlg::OnBnClickedButton1()
{
MSG msg;
関数名 OnBnClickedButton1
機能 セマフォで同期 ボタン押下イベント
*************************************************/
void CThreadSample2Dlg::OnBnClickedButton1()
{
MSG msg;
count = 0;
threadno = 0;
//複数スレッド(5スレッド)起動
for (int i = 0; i < 5; i++) {
//スレッド番号(IDC_EDIT2に表示する)
threadno = (i+1);
TRACE(L"スレッド %d 起動¥n",threadno);
threadno = 0;
//複数スレッド(5スレッド)起動
for (int i = 0; i < 5; i++) {
//スレッド番号(IDC_EDIT2に表示する)
threadno = (i+1);
TRACE(L"スレッド %d 起動¥n",threadno);
AfxBeginThread(CountUpThread, this, 0, 0, NULL);
while (PeekMessage(&msg, this->GetSafeHwnd(), 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
while (PeekMessage(&msg, this->GetSafeHwnd(), 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(300);
}
}
}
}
/*************************************************
関数名 CountUpThread
機能 ダイアログの変数をカウントアップして表示
*************************************************/
UINT __cdecl CountUpThread(LPVOID p) {
CThreadSample2Dlg* pDlg = (CThreadSample2Dlg*)p;
CString cs;
MSG msg;
CSingleLock singlelock(&(pDlg->m_cSmp));
関数名 CountUpThread
機能 ダイアログの変数をカウントアップして表示
*************************************************/
UINT __cdecl CountUpThread(LPVOID p) {
CThreadSample2Dlg* pDlg = (CThreadSample2Dlg*)p;
CString cs;
MSG msg;
CSingleLock singlelock(&(pDlg->m_cSmp));
//スレッド番号を更新
cs.Format(L"%d", pDlg->threadno);
pDlg->m_EdtThread.SetWindowTextW(cs);
cs.Format(L"%d", pDlg->threadno);
pDlg->m_EdtThread.SetWindowTextW(cs);
//1スレッドで100カウントアップする
for(int i=0;i<100;i++){
//複数スレッドからcountにアクセスする際に、いずれか1スレッドからしか
//使用できないように排他制御する
//CSingleLockについてはDeveloperNetWork参照
singlelock.Lock();
pDlg->count++;
singlelock.Unlock();
for(int i=0;i<100;i++){
//複数スレッドからcountにアクセスする際に、いずれか1スレッドからしか
//使用できないように排他制御する
//CSingleLockについてはDeveloperNetWork参照
singlelock.Lock();
pDlg->count++;
singlelock.Unlock();
//ダイアログのエディットボックスに表示
cs.Format(L"%d", pDlg->count);
pDlg->m_EdtCount.SetWindowTextW(cs);
cs.Format(L"%d", pDlg->count);
pDlg->m_EdtCount.SetWindowTextW(cs);
while (PeekMessage(&msg, pDlg->GetSafeHwnd(), 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
TRACE(L"count = " + cs + L"¥n");
Sleep(100);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
TRACE(L"count = " + cs + L"¥n");
Sleep(100);
}
return 0;
}
}
よろしければポチッと押してください