マルチスレッド・マルチプロセスでは、排他制御が重要。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();
}
}
}
}