マルチスレッド・マルチプロセスでは、排他制御が重要。MFCでは、排他制御の為のロッククラスが用意されている。
クラス | 使途 |
---|---|
CEvent | イベントが発生するのを待つのに使うみたいだけど、具体的な状況がいまいち分からない(爆) |
CSemaphore | セマフォ。Windowsでは、スレッド間ロックに使用できる。 |
CMutex | ミューテックス。Windowsでは、プロセス間ロックに使用できる。同じプログラムを複数起動させない為の制御に使うのが有名。 |
CCriticalSection | その他だそうで…ヘルプによれば。 |
なお、これらのクラスを使うには「afxmt.h」をインクルードする必要がある。
1プロセス内で複数スレッドからアクセスする際に、一度にどれか1箇所からしか使わないように制御する。
タイマー割込みとOnDraw()で使う描画用DCを、同時にどちらかしか使えないよう排他制御できる。
(このケースで 排他制御をしないと、意図しないちらつきが出たりして大変…てゆーか、それで済めば超ラッキー)
CHogeView.h:
#include <afxmt.h> class CHogeView : public CView { private: CSemaphore m_DrawSync; //ロックオブジェクト virtual void OnDraw(CDC* pDC); // このビューを描画する際にオーバーライドされます。 static UINT m_uiTimerID; //タイマー割込みID static void CALLBACK TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); 〜 };
CHogeView.cpp:
void CHogeView::OnDraw(CDC* pDC) { CSingleLock lock(&m_DrawSync); lock.Lock(); 〜描画処理(裏DCを使用)〜 lock.Unlock(); }
UINT CHogeView::m_uiTimerID = 0; void CALLBACK CHogeView::TimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { if (uTimerID==m_uiTimerID && m_uiTimerID!=0) { CHogeView *pView = (CHogeView*)dwUser; if (pView) { CSingleLock lock(&m_DrawSync); if (!lock.IsLocked()) { lock.Lock(); 〜タイマー処理本体(裏DCへ描き込み)〜 lock.Unlock(); } } } }