深入浅出Win32多线程设计之MFC的多线程(2)
来源:互联网 发布:隔音耳塞 知乎 编辑:程序博客网 时间:2024/05/05 01:20
2.线程间通信
MFC中定义了继承自CSyncObject类的CCriticalSection 、CCEvent、CMutex、CSemaphore类封装和简化了WIN32 API所提供的临界区、事件、互斥和信号量。使用这些同步机制,必须包含"Afxmt.h"头文件。
作为CSyncObject类的继承类,我们仅仅使用基类CSyncObject的接口函数就可以方便、统一的操作CCriticalSection 、CCEvent、CMutex、CSemaphore类,下面是CSyncObject类的原型:
{
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;
};
CSyncObject类最主要的两个函数是Lock和Unlock,若我们直接使用CSyncObject类及其派生类,我们需要非常小心地在Lock之后调用Unlock。
MFC提供的另两个类CSingleLock(等待一个对象)和CMultiLock(等待多个对象)为我们编写应用程序提供了更灵活的机制,下面以实际来阐述CSingleLock的用法:
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
}
}
上述实例讲述了用CSingleLock对Windows GDI相关对象进行保护的方法,下面再给出一个其他方面的例子:
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); //启动拷贝线程
上面的例子中启动了两个线程EvaluateThread和CopyThread,线程EvaluateThread把10个数赋值给数组array1[],线程CopyThread将数组array1[]拷贝给数组array2[]。由于数组的拷贝和赋值都是整体行为,如果不以互斥形式执行代码段:
for (int i = 0; i < 10; i++)
array1[i] = i;
和
for (int i = 0; i < 10; i++)
array2[i] = array1[i];
其结果是很难预料的!
除了可使用CCriticalSection、CEvent、CMutex、CSemaphore作为线程间同步通信的方式以外,我们还可以利用PostThreadMessage函数在线程间发送消息:
BOOL PostThreadMessage(DWORD idThread, // thread identifier
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
- 深入浅出Win32多线程设计之MFC的多线程(2)
- 深入浅出Win32多线程设计之MFC的多线程
- 深入浅出Win32多线程设计之MFC的多线程
- 深入浅出Win32多线程设计之MFC的多线程(1)
- 深入浅出Win32多线程设计之MFC的多线程(3)
- 深入浅出Win32多线程设计之MFC的多线程(4)
- 深入浅出Win32多线程设计之MFC的多线程(I)
- 深入浅出Win32多线程设计之MFC的多线程(II)
- 深入浅出Win32多线程设计之(四):MFC的多线程
- 深入浅出Win32多线程设计之四:MFC的多线程
- 深入浅出Win32多线程设计之(四):MFC的多线程
- 深入浅出Win32多线程设计之MFC的多线程
- 深入浅出Win32多线程设计之MFC的多线程
- 【C++】深入浅出Win32多线程设计之MFC的多线程
- Win32多线程设计之MFC的多线程
- 深入浅出Win32多线程程序设计--之MFC的多线程
- 深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)
- Win32多线程之设计多线程程序需要注意的问题
- 消息钩子函数入门篇
- 首页泳装SHOW项目总结
- SQL行转换成列
- 绝对值得珍藏的端口大全
- 在BCB2007(SP3)上安装最新的Boost 1.34.1
- 深入浅出Win32多线程设计之MFC的多线程(2)
- 深入浅出Win32多线程设计之MFC的多线程(3)
- SQL Watch for SQL Server Trial from Quest Software
- SHA1加密的C++实现
- 论文写作小技巧
- MyEclipse 开发 SSH 整合时 java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit 解决方案
- p2p聊天系统(北大青鸟大二寒假作业)
- top 10 algorithms in data mining
- 申请QQ号码“永久保护”被拒,质疑腾讯服务