2.线程间通信
MFC中定义了继承自CSyncObject类的CCriticalSection 、CCEvent、CMutex、CSemaphore类封装和简化了WIN32 API所提供的临界区、事件、互斥和信号量。使用这些同步机制,必须包含"Afxmt.h"头文件。
作为CSyncObject类的继承类,我们仅仅使用基类CSyncObject的接口函数就可以方便、统一的操作CCriticalSection 、CCEvent、CMutex、CSemaphore类,下面是CSyncObject类的原型:
class CSyncObject : public CObject { DECLARE_DYNAMIC(CSyncObject) // Constructor public: CSyncObject(LPCTSTR pstrName); // Attributes public: operator HANDLE() const; HANDLE m_hObject; // Operations virtual BOOL Lock(DWORD dwTimeout = INFINITE); virtual BOOL Unlock() = 0; virtual BOOL Unlock(LONG /* lCount */, LPLONG /* lpPrevCount=NULL */) { return TRUE; } // Implementation public: virtual ~CSyncObject(); #ifdef _DEBUG CString m_strName; virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif friend class CSingleLock; friend class CMultiLock; }; |
class CThreadSafeWnd { public: CThreadSafeWnd(){} ~CThreadSafeWnd(){} void SetWindow(CWnd *pwnd) { m_pCWnd = pwnd; } void PaintBall(COLORREF color, CRect &rc); private: CWnd *m_pCWnd; CCriticalSection m_CSect; }; void CThreadSafeWnd::PaintBall(COLORREF color, CRect &rc) { CSingleLock csl(&m_CSect); //缺省的Timeout是INFINITE,只有m_Csect被激活,csl.Lock()才能返回 //true,这里一直等待 if (csl.Lock()) ; { // not necessary //AFX_MANAGE_STATE(AfxGetStaticModuleState( )); CDC *pdc = m_pCWnd->GetDC(); CBrush brush(color); CBrush *oldbrush = pdc->SelectObject(&brush); pdc->Ellipse(rc); pdc->SelectObject(oldbrush); GdiFlush(); // don't wait to update the display } } |
int array1[10], array2[10]; CMutexSection section; //创建一个CMutex类的对象 //赋值线程控制函数 UINT EvaluateThread(LPVOID param) { CSingleLock singlelock; singlelock(§ion); //互斥区域 singlelock.Lock(); for (int i = 0; i < 10; i++) array1[i] = i; singlelock.Unlock(); } //拷贝线程控制函数 UINT CopyThread(LPVOID param) { CSingleLock singlelock; singlelock(§ion); //互斥区域 singlelock.Lock(); for (int i = 0; i < 10; i++) array2[i] = array1[i]; singlelock.Unlock(); } } AfxBeginThread(EvaluateThread, NULL); //启动赋值线程 AfxBeginThread(CopyThread, NULL); //启动拷贝线程 |
for (int i = 0; i < 10; i++) array1[i] = i; |
for (int i = 0; i < 10; i++) array2[i] = array1[i]; |
BOOL PostThreadMessage(DWORD idThread, // thread identifier UINT Msg, // message to post WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); |