![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
いつも大変お世話になっております。
VC++初心者です。
現在、下記のサイトでマルチスレッドを勉強していますが、
そのスレッドの呼び出し方が分かりません。
具体的にどのように書けば宜しいのでしょうか。
http://www.takebay.net/~daigo-ao/paddlewiki.pl/t …
mainではないですが、別のクラスから呼び出そうと思い、
以下のように書きましたが、駄目でした。
CHoge aaa;
aaa.RunThread();
お手数ですが、よろしくお願い致します。
No.1ベストアンサー
- 回答日時:
こんにちは。
動いてはいますが、10秒間停止した後に終了しています。
例えばダイアログ上のボタン1で開始、ボタン2で停止するならば、上記URLの
Sleep(10000);// 10秒待つ
m_isAlive = false;// スレッドを終了させる
をコメントアウトして、ダイアログのメンバ変数に
CHoge* m_pHoge;
を追加、
ボタン1で、
m_pHoge = new CHoge();
ボタン2で
delete m_pHoge;
m_pHoge = NULL;
といった感じでではないでしょうか。
この回答への補足
ご回答、ありがとうござます。
毎回のご教授、感謝しております。
できました!
ありがとうございました。
今回の問題を更に発展させて、
以下の問題についてご指導頂けませんでしょうか。
・ボタン2をを使わずにスレッドの処理が終了したら、
ボタン2の処理内容(スレッドの削除)を行うには?
・ボタン1を押下のたびに新スレッドを作成するには?
(CHoge* m_pHogeを配列にしてあげればよいのでしょうか。)
・新規にボタン3を設けて、現在動いているスレッドを強制終了するには?
よろしくお願いします。
No.2
- 回答日時:
こんばんは。
補足頂きました。・ボタン2をを使わずにスレッドの処理が終了したら、ボタン2の処理内容(スレッドの削除)を行うには?
スレッド側からダイアログクラスに向かって終了通知用のメッセージをポストします。
・ボタン1を押下のたびに新スレッドを作成するには?(CHoge* m_pHogeを配列にしてあげればよいのでしょうか。)
CArray<CHoge*>を使用した方が楽になると思います。
・新規にボタン3を設けて、現在動いているスレッドを強制終了するには?
CArray<CHoge*>の全要素を回してスレッドを止める等でしょうか。
配列の要素を操作中、スレッド間で競合する可能性もあると思うので、クリティカルセクションで排他を行わないとまずそうです。
取りあえず、ボタン1でスレッドの作成、ボタン2で稼働中の全てのスレッドの停止、1秒程でスレッドの自動停止をしていますが、色々アラもあると思うので参考程度で。
//TestDlg.cppの一番上、ヘッダのインクルードよりは下に置く(此処から)
//終了通知を受ける為のメッセージ
#define WM_ENDTHREAD (WM_USER + 100)
//スレッドクラス
class CHoge
{
public:
enum
{
READY,
RUNNING,
SUCCESS_END,
FORCE_EXIT,
};
private:
static UINT StaticProc(LPVOID pParam)
{
CHoge* pHoge = static_cast<CHoge*>(pParam);
return pHoge->ThreadProc();
}
public:
explicit CHoge(CTestDlg* pParent)
: m_pThread(NULL), m_pParent(pParent), m_iState(READY), m_iCount(0)
{
}
~CHoge()
{
}
bool RunThread()
{
if(m_pThread)
return false;
m_iState = RUNNING;
m_pThread = ::AfxBeginThread(StaticProc, this, 0, 0, CREATE_SUSPENDED);
m_pThread->m_bAutoDelete = TRUE;
m_pThread->ResumeThread();
return true;
}
void SetState(int iState)
{
m_cs.Lock();
m_iState = iState;
m_cs.Unlock();
}
int GetState() const
{
m_cs.Lock();
const int iState = m_iState;
m_cs.Unlock();
return iState;
}
HANDLE GetHandle() const
{
return m_pThread ? m_pThread->m_hThread : NULL;
}
private:
UINT ThreadProc()
{
while(1)
{
::Sleep(200);
switch(this->GetState())
{
case SUCCESS_END:
TRACE("終了\n");
m_pParent->PostMessage(WM_ENDTHREAD, 0, reinterpret_cast<LPARAM>(this));
return 0;
case FORCE_EXIT:
TRACE("強制終了\n");
return 0;
default:
TRACE("実行中\n");
this->Running();
}
}
return 0;
}
void Running()
{
//此処で処理をする
//条件を満たしたらステートを変える
if(++m_iCount > 5)
this->SetState(SUCCESS_END);
}
mutable CCriticalSection m_cs;
CWinThread* m_pThread;
CTestDlg* m_pParent;
int m_iState;
int m_iCount;
};
//(此処まで)
// TestDlg.h : ヘッダー ファイル
//
#pragma once
//追加
#include<afxmt.h>
//追加
class CHoge;
// CTestDlg ダイアログ
class CTestDlg : public CDialog
{
friend CHoge;
// コンストラクション
public:
CTestDlg(CWnd* pParent = NULL);// 標準コンストラクタ
// ダイアログ データ
enum { IDD = IDD_TEST_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV サポート
// 実装
private:
//追加
CArray<CHoge*> m_pool;
//追加
CCriticalSection m_cs;
//追加
void StartThread();
//追加
void RemoveEndThread(CHoge* pHoge);
//追加
void StopAllThread();
protected:
HICON m_hIcon;
// 生成された、メッセージ割り当て関数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
//クラスウィザードから追加
afx_msg void OnBnClickedButton1();
//クラスウィザードから追加
afx_msg void OnBnClickedButton2();
//追加
afx_msg LRESULT OnEndThread(WPARAM wParam, LPARAM lParam);
};
// TestDlg.cpp : ソース ファイル
//
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
//省略
//...
//省略
//追加
ON_MESSAGE(WM_ENDTHREAD,&CTestDlg::OnEndThread)
END_MESSAGE_MAP()
//スレッドを配列に入れてスタート
void CTestDlg::StartThread()
{
m_cs.Lock();
CHoge* pHoge = new CHoge(this);
m_pool.Add(pHoge);
pHoge->RunThread();
m_cs.Unlock();
}
//pHogeを配列から抜き取る
void CTestDlg::RemoveEndThread(CHoge* pHoge)
{
m_cs.Lock();
for(int i = 0; i < m_pool.GetCount(); ++i)
{
if(m_pool[i] != pHoge)
continue;
m_pool.RemoveAt(i);
break;
}
m_cs.Unlock();
::WaitForSingleObject(pHoge->GetHandle(), INFINITE);
delete pHoge;
}
//全てのスレッドを止める
void CTestDlg::StopAllThread()
{
CArray<HANDLE> handles;
m_cs.Lock();
for(int i = 0; i < m_pool.GetCount(); ++i)
{
handles.Add(m_pool[i]->GetHandle());
m_pool[i]->SetState(CHoge::FORCE_EXIT);
}
::WaitForMultipleObjects(handles.GetCount(), handles.GetData(), TRUE, INFINITE);
for(int i = 0; i < m_pool.GetCount(); ++i)
delete m_pool[i];
m_pool.RemoveAll();
m_cs.Unlock();
}
//ボタン1が押された
void CTestDlg::OnBnClickedButton1()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
this->StartThread();
}
//ボタン2が押された
void CTestDlg::OnBnClickedButton2()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
this->StopAllThread();
}
//スレッドが正常終了した時に来る通知
LRESULT CTestDlg::OnEndThread(WPARAM wParam, LPARAM lParam)
{
this->RemoveEndThread(reinterpret_cast<CHoge*>(lParam));
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 分譲マンション 古い分譲の初理事(※副理事)の対応について 2 2022/11/04 01:26
- その他(プログラミング・Web制作) Pythonで複数のメソッドをまとめて管理する方法について 1 2023/03/30 00:01
- 結婚式・披露宴 私は35歳の男で今年10月に挙式を行う予定です。 今は招待状の作成中で誰を招待するか大体決まっていま 7 2023/06/14 17:56
- Visual Basic(VBA) vba Sleep関数について教えてください 1 2023/01/18 10:18
- 子育て 高1と中1の息子のパパママ呼びについて 13 2022/05/15 22:10
- JavaScript jsonテキストデータの並び替えができるサービスを教えてください 2 2022/08/05 20:16
- その他(生活家電) ミュート機能のあるインターホンでも、外で訪問者が呼び出しベルを押したらピンポンという音は鳴りますか? 3 2023/07/18 10:41
- gooのスマホ lineの着信画面ならず「不在着信」になる 1 2022/07/07 12:31
- Skype Skype通話について 1 2023/05/24 14:00
- モテる・モテたい 好きな人に呼ばれたい呼び名。 1 2022/06/04 19:09
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VC++スレッドの正しい終了のさ...
-
pthread_mutex_lock の応答時間
-
メインスレッドのPostMessageと...
-
スレッドの安全な終了のさせ方
-
Win32APIでのスレッド処理
-
スレッドの監視方法について
-
WaitForSingleObjectの使い方に...
-
スレッドの終了の仕方
-
スレッドがサスペンドされてい...
-
C# スレッド終了の監視について
-
別スレッドからメインダイアロ...
-
スレッド終了を待つ間に開放さ...
-
DirectX キーが入力されるまで...
-
C言語で一定時間待機後、再実行
-
Windows上で、シグナル(SIGTERM...
-
頭冷やし終えました。スクリー...
-
pthread_cond_wait 取りこぼし?
-
同一スレッドで、ロックをかけ...
-
スレッド一覧の取得
-
Macターミナルで実行中のプログ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
VC++スレッドの正しい終了のさ...
-
スレッドの監視方法について
-
スレッドの安全な終了のさせ方
-
Windows上で、シグナル(SIGTERM...
-
マルチスレッドプログラミング...
-
スレッドの終了の仕方
-
スレッドにて同一メモリの書き...
-
VB2005 シリアル通信のClose処理
-
スレッドの終了はどうやるんで...
-
スレッドでWM_TIMERを受け取れない
-
同一スレッドで、ロックをかけ...
-
マルチスレッドのスレッド数を...
-
WaitForMultipleObjectのイベン...
-
MFC通信プログラムマルチスレッ...
-
CWnd::OnTimerのスレッドの取得
-
待機関数(WaitForMultipleObjec...
-
LinuxでDoEvents()同等機能
-
【VC++6.0(MFC)】スレッドの呼...
-
pthread_cond_wait 取りこぼし?
おすすめ情報