MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
MFCの基礎 - マルチスレッドのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
MFCの基礎 - マルチスレッド
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == MFCアプリケーションにおいて、マルチスレッドを使用する方法について記述する。<br><br> == 作成手順 == まず、クラスにワーカースレッド関数(静的)とワーカースレッド本体の関数を追加する。<br> ワーカースレッド本体の関数では、静的でないメンバ変数およびメンバ関数が使用できる。<br> ワーカースレッド関数では、静的でないメンバ変数およびメンバ関数が使用できないと考えている人がいるが、<br> 下記のサンプルコードのようにすればクラスの関数はワーカースレッド関数にて行うことができる。<br><br> == サンプルコード == <source lang="cpp"> // CFileView.h class CFileView { private: CWinThread *m_pLoadXMLThread public: static UINT LoadXMLThreadFunc(void* pParam); // XMLファイル読み込み時のスレッド制御関数 void LoadXMLThreadFunc(); // XMLファイル読み込みスレッド処理関数 }; // CFileView.cpp void CFileView::OnButtonClick() { // XML読み込み処理スレッド関数を実行 m_pLoadXMLThread = ::AfxBeginThread(LoadXMLThreadFunc, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); ASSERT(m_pLoadXMLThread); if(m_pLoadXMLThread) { m_pLoadXMLThread->m_pMainWnd = this; m_pLoadXMLThread->m_bAutoDelete = TRUE; // スレッド処理の開始 m_pLoadXMLThread->ResumeThread(); while(WaitForSingleObject(pTh->m_hThread, 100) == WAIT_TIMEOUT) { // フリーズしないようにする MSG msg; while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } delete pTh; } } //---------------------------------------------------------------------------------- // ワーカースレッド関数(静的) // @brief XMLファイル読み込み時のスレッド関数 // @param[in] pParam : 通常CFileViewクラスへのポインタが渡される // @description [説明] // XMLファイル読み込み処理を別スレッドで行う。 // ここでは処理本体を呼ぶだけである。 // @return 成功時 0 を返します。 //---------------------------------------------------------------------------------- UINT CFileView::LoadXMLThreadFunc(void *pParam) { CFileView *pFileView = dynamic_cast<CFileView*>(reinterpret_cast<CWnd*>(pParam)); if(pFileView) { pFileView->LoadXMLThreadFunc(); } return THREAD_EXIT_CODE; } // ワーカースレッド本体の関数 // スレッドの開始 void CFileView::LoadXMLThreadFunc() { // スレッド本体の処理 } </source> <br><br> == 注意事項 == UpdateData(TRUE)およびUpdateData(FALSE)等はスレッド内で呼ぶことができない。<br> AfxGetMainWnd()の戻り値は、CWinThread *m_pLoadXMLThread->m_pMainWndに渡したウィンドウである。<br> 設定しないとNULLが返り、また、ダイアログのCreate関数も呼ぶことができない。<br> そこで、スレッドの処理と同期してUIを更新する場合(UpdateData(TRUE)をスレッドから同期して呼ぶ場合)は、<br> 下記のようにスレッド内からメインウィンドウにメッセージを送る。<br> <br> <source lang="cpp"> // スレッドからメイン処理にメッセージを送る & 受け取って処理 //------------------------------------------------------------------------ // USER_MESSAGE //------------------------------------------------------------------------ // stdafx.h #define WM_USER_COMPLETE_LOAD_XML (WM_USER + 1) // XMLデータの読み込みの完了メッセージ // CFileView.h BEGIN_MESSAGE_MAP(CFileView, CDockablePane) // UserMessage ON_MESSAGE(WM_USER_COMPLETE_LOAD_XML, &CFileView::OnCompleteLoadXML) END_MESSAGE_MAP() // CFileView.cpp // ワーカースレッド関数の本体にて // XMLファイルの読み込みが完了したメッセージを送信 AfxGetMainWnd()->SendMessage(WM_USER_COMPLETE_LOAD_XML, (WPARAM)&firstIndex, (LPARAM)firstFilePath.GetString()); // CFileView.cpp class CFileView { // 追加 afx_msg LRESULT OnCompleteLoadXML(WPARAM wParam, LPARAM lParam ); } </source> <br> 後は、SendMessage関数を受け取った側で処理を行えばよい。<br> 受け取り側では、UpdateData(TRUE)およびUpdateData(FALSE)等を呼ぶことができる。<br> ここでスレッドを待つWaitForSingleObject関数を使用した場合、デッドロックになるので気をつけること。<br> スレッドの終了時に何らかの処理を行うのであれば、今回のようにスレッド終了時に"メッセージをメインウィンドウへ送る"ことで解決できる。<br> <br><br> __FORCETOC__ [[カテゴリ:MFC]]
MFCの基礎 - マルチスレッド
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse