開発環境はVC++6.0 OS2000 MFCです。
スレッドの勉強を始めたばかりのものです、過去ログを拝見しましたが分かりませんでしたので
投稿させて頂きました。
OnStartボタンで1000までカウントを行なうスレッドを実行します。
OnStopボタンでカウント1000が終了するまでにスレッドを止めたいのですが
下記のソースでは終了できませんでした。
何が行けないのでしょうか?宜しくお願い致します。
void CThreadDlg::OnStart() {
m_SrThreadStatus = AfxBeginThread((AFX_THREADPROC)Thread1, (LPVOID)
this,THREAD_PRIORITY_NORMAL);
}
void CThreadDlg::OnStop()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
if(m_SrThreadStatus){
SrThreadEvent.SetEvent();
}
}
UINT Thread1(LPVOID pvParam)
{
CThreadDlg *pDlg = (CThreadDlg*)pvParam;
char lpszStr[64];
int i=0; /* カウンタ変数クリア */
while (i<1000) { /* 1000までカウント */
i++; /* カウンタを一つ増やす */
wsprintf(lpszStr,Thread1 %8d,i);
pDlg->m_edit.SetWindowText(lpszStr); /* カウンタの数を表示 */
Sleep(1); /* ウエイト */
}
return(0);
}
> void CThreadDlg::OnStop()
> {
> // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
> if(m_SrThreadStatus){
> SrThreadEvent.SetEvent();
> }
> }
SrThreadEventの定義はどうなっていますか?
スレッド側にSrThreadEventがセットされたら処理を終了する
というコードがありませんけど…
SrThreadEventはヘッダーにてCEvent SrThreadEvent;と宣言しております。
勘違いをしておりましてSrThreadEvent.SetEvent();
で終了するものばかり思っておりました。
WaitForSingleObjectを解除する処理だとわかりました。
OnStop関数を修正しなくてなりません。
調べておりますが、ちょっと出口がみつからないのですが…
お手数掛けます。
> while (i<1000) { /* 1000までカウント */
>
> i++; /* カウンタを一つ増やす */
>
> wsprintf(lpszStr,Thread1 %8d,i);
> pDlg->m_edit.SetWindowText(lpszStr); /* カウンタの数を表示 */
>
> Sleep(1); /* ウエイト */
> }
上記ループ内でCThreadDlgのメンバ変数を参照(中断判定用を新規に作成)し、値によってルー
プを抜ける処理を入れるのがよいかと思います。
皆さんすみません、質問内容は違いますが
同じソースでのマルチポストをしてしまいました。
以後、同じ繰り返しをしませんので宜しくお願い致します。
WaitForSingleObjectが入ったソースですが以下のように修正して
終了するようになりました。
m_Thread1Stopはint型で作成しました。
こんな終了の仕方でいいのか心配です。ソース的に綺麗なのか、一般的な終了の仕方があるのか
アドバイス頂けませんか?
void CThreadDlg::OnStop()
{
m_Thread1Stop = 1;
if(m_SrThreadStatus){
SrThreadEvent.SetEvent();
}
}
UINT Thread1(LPVOID pvParam)
{
CThreadDlg *pDlg = (CThreadDlg*)pvParam;
char lpszStr[64];
int i=0; /* カウンタ変数クリア */
while (i<1000) { /* 1000までカウント */
if(pDlg->m_Thread1Stop == NULL){
i++; /* カウンタを一つ増やす */
wsprintf(lpszStr,Thread1 %8d,i);
pDlg->m_edit.SetWindowText(lpszStr); /* カウンタの数を表示 */
WaitForSingleObject(pDlg->SrThreadEvent, 100);
Sleep(1); /* ウエイト */
}else{
pDlg->m_SrThreadStatus = NULL;
return(0);
}
}
m_Thread1Stopはpublicですから、他からも制御出来てしまいますのでprivateメンバにしま
す。
その場合Thread1()関数からはアクセス出来なくなるのでThread1()もCThreadDlgクラスのメン
バ関数とし、staticにしてあげればOKですね。
m_Thread1Stopもstaticにします。
OnOk()等のダイアログを終了する関数にもm_Thread1Stopの値をセットするようにします。
で、WaitForSingleObject()でスレッド処理が終了するまで待つ。
WaitForSingleObject()の使い方が違うくないですか?
別の用途でやっているならいいのですが。
> pDlg->m_SrThreadStatus = NULL;
> return(0);
この手の処理は個人的にはループの外で行うようにします。
ループはブレイクで抜けています。
その辺は好みの問題なので、1例を挙げたまでという事で。
基礎不足ですみません。
>m_Thread1Stopもstaticにします。
今は
初期はNULL
OnStopで1
Thread1を抜ける時はNULL
の流れですが、staticにすることで何がかわるのですか?
> staticにすることで何がかわるのですか?
何故本を読まないんだろう…
投げやり質問大変失礼しました。
1つずつ調べたいと思います。
m_Thread1StopをプライベートにすることでThread1()関数からはアクセス出来なくなるので
Thread1()もCThreadDlgクラスのメンバ関数とし、staticにするとありますが
分からなかったので本を見ましたがかかれておりません。
お手数ですがNETなどで調べたいと思いますのでキーワードなど教えて頂けたらと思います。
検索するキーワードではないですが、
・なぜThread1()をメンバにする際にstaticとしなければならないのか?
は納得出来ているでしょうか?
その辺から検索してもひっかかるかもしれません。
なぜm_Thread1Stopをstaticにしなければならないのか?と思ったら、staticにしないでコン
パイルするのも手です。その辺でもピンと来るかもしれないですし。
スレッド処理とは直接関係ない基本的な事なので、επιστημηさんは何故本を読まないんだろ
う…と言われたのだと思います。
相変わらずですね…
>m_Thread1StopをプライベートにすることでThread1()関数からはアクセス出来なくなるので
>Thread1()もCThreadDlgクラスのメンバ関数とし、staticにするとありますが
>分からなかったので本を見ましたがかかれておりません。
上記文章のうちの「どこが」分からないのですか?
「全部」というのはなしですよ。あなたは、人が言った(書いた)ことをそのまま書き並べた
だけです。そもそもそういう態度が、自分で努力をしていないと思われる(事実?)わけですが。
間違っていたら指摘して下さい。
>なぜThread1()をメンバにする際にstaticとしなければならないのか?
m_Thread1Stopを静的変数にするとm_Thread1Stopを処理する為に
Thread1()もstaticをつけ静的メンバ関数(静的メンバ関数は静的データメンバしか扱わない為)としな
くてはならない。
>m_Thread1Stopはpublicですから、他からも制御出来てしまいますのでprivateメンバにしま
>す。
これはクラス内で共通する変数を持たせたいからprivateで隠蔽化させる為
とここまで解釈をしておりますが・・・。
> m_Thread1Stopを静的変数にするとm_Thread1Stopを処理する為に
> Thread1()もstaticをつけ静的メンバ関数(静的メンバ関数は静的データメンバしか扱わない
> 為)としな
> くてはならない。
う”惜しい。逆です。
Thread1()をstaticにする必要があるからm_Thread1Stopもstaticにしないとアクセス出来な
い為です。
> これはクラス内で共通する変数を持たせたいからprivateで隠蔽化させる為
隠蔽化する為、privateのクラスメンバとした訳ですね。