对同步类CMutex 的使用方法就是按照本文所讲述的融入的方法来实现的。同步访问类CSingleLock 的锁对象则在各线程的具体实现中定义。
---- 下面介绍该例程的具体实现:
利用AppWizard 生成一个名为Mutexes 基于对话框的应用程序框架。
利用对话框编辑器在对话框中填加以下内容:三个组合框,三个复选框和一个列表框。三个组合框分别允许改变进程优先级和两个线程优先级,其ID 分别设置为:IDC_PRIORITYCLASS、IDC_DSPYTHRDPRIORITY 和IDC_CNTRTHRDPRIORITY。三个复选框分别对应着同步机制选项、显示计数线程执行选项和暂停选项,其ID 分别设置为IDC_SYNCHRONIZE、IDC_SHOWCNTRTHRD 和IDC_PAUSE。列表框用于显示线程显示程序中两个线程的共同操作对象m_strNumber,其ID 设置为IDC_DATABOX。
创建类CWinThread 的派生类CExampleThread。该类将作为本程序中使用的两个线程类:CCounterThread 和CDisplayThread 的父类。这样做的目的仅是为了共享两个线程类的共用变量和函数。
---- 在CExampleThread 的头文件中填加如下变量:
CMutexesDlg * m_pOwner;//指向类CMutexesDlg指针
BOOL m_bDone;//用以控制线程执行
及函数:
void SetOwner(CMutexesDlg* pOwner)
{ m_pOwner=pOwner; };//取类CMutexesDlg的指针
然后在构造函数当中对成员变量进行初始化:
m_bDone=FALSE;//初始化允许线程运行
m_pOwner=NULL;//将该指针置为空
m_bAutoDelete=FALSE;//要求手动删除线程对象
创建两个线程类CCounterThread 和CdisplayThread。这两个线程类是CExampleThread 的派生类。分别重载两个线程函数中的::Run() 函数,实现各线程的任务。在这两个类当中分别加入同步访问类的锁对象sLock,这里将根据同步机制的复选与否来确定是否控制对共享资源的访问。不要忘记需要加入头文件#include "afxmt.h"。
---- 计数线程::Run() 函数的重载代码为:
int CCounterThread::Run()
{
BOOL fSyncChecked;//同步机制复选检测
unsigned int nNumber;//存储字符串中整数
if (m_pOwner == NULL)
return -1;
//将同步对象同锁对象联系起来
CSingleLock sLock(&(m_pOwner- >m_mutex));
while (!m_bDone)//控制线程运行,为终止线程服务
{
//取同步机制复选状态
fSyncChecked = m_pOwner- >
IsDlgButtonChecked(IDC_SYNCHRONIZE);
//确定是否使用同步机制
if (fSyncChecked)
sLock.Lock();
//读取整数
_stscanf((LPCTSTR) m_pOwner- >m_strNumber,
_T("%d"), &nNumber);
nNumber++;//加1
m_pOwner- >m_strNumber.Empty();//字符串置空
while (nNumber != 0) //更新字符串
{
m_pOwner- >m_strNumber +=
(TCHAR) (''0''+nNumber%10);
nNumber /= 10;
}
//调整字符串顺序
m_pOwner- >m_strNumber.MakeReverse();
//如果复选同步机制,释放资源
if (fSyncChecked)
sLock.Unlock();
//确定复选显示计数线程
if (m_pOwner- >IsDlgButtonChecked(IDC_SHOWCNTRTHRD))
m_pOwner- >AddToListBox(_T("Counter: Add 1"));
}//结束while
m_pOwner- >PostMessage(WM_CLOSE, 0, 0L);
return 0;
}
显示线程的::Run()函数重载代码为:
int CDisplayThread::Run()
{
BOOL fSyncChecked;
CString strBuffer;
ASSERT(m_pOwner != NULL);
if (m_pOwner == NULL)
return -1;
CSingleLock sLock(&(m_pOwner- >m_mutex));
while (!m_bDone)
{
fSyncChecked = m_pOwner- >
IsDlgButtonChecked(IDC_SYNCHRONIZE);
if (fSyncChecked)
sLock.Lock();
//构建要显示的字符串
strBuffer = _T("Display: ");
strBuffer += m_pOwner- >m_strNumber;
if (fSyncChecked)
sLock.Unlock();
//将字符串加入到列表框