MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
MFCの基礎 - マルチスレッドのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
MFCの基礎 - マルチスレッド
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == MFCアプリケーションにおいて、マルチスレッドを使用する方法について記述する。<br><br> == 作成手順 == # ワーカースレッド制御関数の定義 #: まず、クラスに静的なワーカースレッド制御関数を定義する。 #: <br> #: ワーカースレッド制御関数は静的であるため、クラスのメンバ変数およびメンバ関数を直接使用することができない。 #: <u>ただし、<code>void*</code>型の引数を渡して特定のキャストを行うことにより、ワーカースレッド制御関数下でクラスのメンバを使用することができる。</u> #: <br> # ワーカースレッド本体の関数の定義 #: 次に、同じクラスに静的ではないワーカースレッド本体の関数を定義する。 #: ワーカースレッド本体の関数では、静的でないメンバ変数およびメンバ関数が使用できる。 <br><br> == サンプルコード == <syntaxhighlight lang="cpp"> // CFileView.hファイル class CFileView { private: CWinThread *m_pLoadXMLThread public: static UINT LoadXMLThreadFunc(void *pParam); // 静的なワーカースレッド制御関数 void LoadXMLThreadFunc(); // ワーカースレッド本体 }; </syntaxhighlight> <br> <syntaxhighlight lang="c++"> // 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 = FALSE; // スレッド処理の開始 m_pLoadXMLThread->ResumeThread(); while (WaitForSingleObject(m_pLoadXMLThread->m_hThread, 100) == WAIT_TIMEOUT) { // ワーカースレッドが終了するまで待機 MSG msg; while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } } delete m_pLoadXMLThread; } // マルチスレッドの応用(ウェイトウィンドウを表示する) //m_pLoadXMLThread = ::AfxBeginThread(LoadXMLThreadFunc, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); //if(m_pLoadXMLThread) { // CRect rc; // HWND hNotifyWnd = CreateDialog(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDD_PROCESSING), this->m_hWnd, (DLGPROC)YCommonProc); // ::ShowWindow(hNotifyWnd, SW_SHOW); // ::GetClientRect(&rc); // ::MoveWindow(hNotifyWnd, (rc.right - rc.left) / 2 - 100, (rc.bottom - rc.top) / 2 - 25, 200, 50, TRUE); // m_pLoadXMLThread->m_pMainWnd = this; // m_pLoadXMLThread->m_bAutoDelete = FALSE; // m_pLoadXMLThread->ResumeThread(); // while(::WaitForSingleObject(m_pLoadXMLThread->m_hThread, 100) == WAIT_TIMEOUT) { // // ワーカースレッドが終了するまで待機 // MSG msg; // while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // ::TranslateMessage(&msg); // ::DispatchMessage(&msg); // } // } // delete m_pLoadXMLThread; // ::DestroyWindow(hNotifyWnd); //} } // 静的なワーカースレッド制御関数 // 引数 : この制御関数が定義されているクラスへのポインタ // 実処理はワーカースレッド本体の関数で行う 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() { // ワーカースレッドで実行する処理 // ...略 } </syntaxhighlight> <br><br> == 画面の更新 == ワーカースレッド内において、<code>UpdateData</code>関数等の画面を描画するような関数は実行することができない。<br> <br> <code>AfxGetMainWnd</code>関数の戻り値は、m_pLoadXMLThread->m_pMainWndに渡したウィンドウである。<br> 設定しない場合は<code>NULL</code>となり、また、ダイアログの<code>Create</code>関数も呼ぶことができない。<br> <br> そのため、ワーカースレッドの処理と同期して画面を更新する場合 (UpdateData(TRUE)をスレッドから同期して実行する場合) は、<br> 以下に示すようにワーカースレッド内からメインウィンドウにメッセージを送信する。<br> メインウインドウは、メッセージを受信して任意の処理を行う。<br> <br> <syntaxhighlight lang="cpp"> // stdafx.hファイル //------------------------------------------------------------------------ // USER_MESSAGE //------------------------------------------------------------------------ #define WM_USER_COMPLETE_LOAD_XML (WM_USER + 1) // XMLデータの読み込みの完了メッセージ </syntaxhighlight> <br> <syntaxhighlight lang="c++"> // CFileView.cppファイル // まず、ワーカースレッドからメイン処理にメッセージを送信する // 次に、メッセージを受信して任意の処理を行う BEGIN_MESSAGE_MAP(CFileView, CDockablePane) // UserMessage ON_MESSAGE(WM_USER_COMPLETE_LOAD_XML, &CFileView::OnCompleteLoadXML) END_MESSAGE_MAP() // ワーカースレッド関数の本体にて // XMLファイルの読み込みが完了したメッセージを送信 AfxGetMainWnd()->SendMessage(WM_USER_COMPLETE_LOAD_XML, (WPARAM)&firstIndex, (LPARAM)firstFilePath.GetString()); </syntaxhighlight> <br> <syntaxhighlight lang="c++"> // CFileView.hファイル class CFileView { // 追加 afx_msg LRESULT OnCompleteLoadXML(WPARAM wParam, LPARAM lParam ); } </syntaxhighlight> <br> 後は、SendMessage関数を受け取った側で処理を行えばよい。<br> 受信側では、UpdateData(TRUE)、および、UpdateData(FALSE)等を呼ぶことができる。<br> <br> <u>この時、スレッドの終了を待機するWaitForSingleObject関数を使用する場合、デッドロックになることに注意する。</u><br> スレッドの終了時に何らかの処理を行うのであれば、上記のようにスレッド終了時に"メッセージをメインウィンドウへ送信する"ことにより解決できる。<br> <br><br> __FORCETOC__ [[カテゴリ:MFC]]
MFCの基礎 - マルチスレッド
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse