导航
  • 主页
  • VC综合技术
  • 互联网技术
  • MFC AppLauncher
  • .NET 技术
  • 界面
  • 进程
  • 算法
  • 硬件/系统
  • 数据库
  • VC++技术资源

200分求多线程例子的源代码

legendhui 2005-05-24 02:55:18
求下面例子的源代码:

---- 下 面 介 绍 该 例 程 的 具 体 实 现:

1. 利 用AppWizard 生 成 一 个 名 为Mutexes 基 于 对 话 框 的 应 用 程 序 框 架。

2. 利 用 对 话 框 编 辑 器 在 对 话 框 中 填 加 以 下 内 容: 三 个 组 合 框, 三 个 复 选 框 和 一 个 列 表 框。 三 个 组 合 框 分 别 允 许 改 变 进 程 优 先 级 和 两 个 线 程 优 先 级, 其ID 分 别 设 置 为:IDC_PRIORITYCLASS、IDC_DSPYTHRDPRIORITY 和IDC_CNTRTHRDPRIORITY。 三 个 复 选 框 分 别 对 应 着 同 步 机 制 选 项、 显 示 计 数 线 程 执 行 选 项 和 暂 停 选 项, 其ID 分 别 设 置 为IDC_SYNCHRONIZE、IDC_SHOWCNTRTHRD 和IDC_PAUSE。 列 表 框 用 于 显 示 线 程 显 示 程 序 中 两 个 线 程 的 共 同 操 作 对 象m_strNumber, 其ID 设 置 为IDC_DATABOX。

3. 创 建 类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;//要求手动删除线程对象
4. 创 建 两 个 线 程 类CCounterThread 和CdisplayThread。 这 两 个 线 程 类 是CExampleThread 的 派 生 类。 分 别 重 载 两 个 线 程 函 数 中 的::Run() 函 数, 实 现 各 线 程 的 任 务。 在 这 两 个 类 当 中 分 别 加 入 同 步 访 问 类 的 锁 对 象sLock, 这 里 将 根 据 同 步 机 制 的 复 选 与 否 来 确 定 是 否 控 制 对 共 享 资 源 的 访 问。 不 要 忘 记 需 要 加 入 头 文 件#include "afxmt.h"。

...全文
138 点赞 收藏 12
写回复
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
kugou123 2005-05-25
应楼主要求,由于得不到满意答案,将可用分返还。
回复
legendhui 2005-05-25
这个例子应该在很多地方能看到的,谁有啊?
回复
qrlvls 2005-05-25
晕,看MSDN比看代码明了吧
回复
luolovegui 2005-05-25
太多了,不想看了。
回复
younggle 2005-05-24
晕,干吗搞的这么烦琐啊?
多线程是很容易的。
回复
wuchi 2005-05-24
回复
sungengyu 2005-05-24
看的头晕。
回复
legendhui 2005-05-24
作了,但是编译时有很多问题,头文件包含复杂,弄不明白
回复
Kudeet 2005-05-24
有了文章,楼主不自己动手做一下?
回复
legendhui 2005-05-24
我的信箱:legendhui@tom.com

请注明你的ID,以便给分
回复
legendhui 2005-05-24
---- 然 后 利 用ClassWizard 填 加 用 于 调 整 进 程 优 先 级、 两 个 线 程 优 先 级 以 及 用 于 复 选 线 程 挂 起 的 函 数。

---- 调 整 进 程 优 先 级 的 代 码 为:

void CMutexesDlg::OnSelchangePriorityclass()
{
DWORD dw;
//取焦点选项
CComboBox* pBox = (CComboBox*)
GetDlgItem(IDC_PRIORITYCLASS);
int nCurSel = pBox- >GetCurSel();
switch (nCurSel)
{
case 0:
dw = IDLE_PRIORITY_CLASS;break;
case 1:
default:
dw = NORMAL_PRIORITY_CLASS;break;
case 2:
dw = HIGH_PRIORITY_CLASS;break;
case 3:
dw = REALTIME_PRIORITY_CLASS;break;
}
SetPriorityClass(GetCurrentProcess(), dw);//调整优先级
}
---- 由 于 调 整 两 个 线 程 优 先 级 的 代 码 基 本 相 似, 单 独 设 置 一 个 函 数 根 据 不 同 的ID 来 调 整 线 程 优 先 级。 该 函 数 代 码 为:

void CMutexesDlg::OnPriorityChange(UINT nID)
{
ASSERT(nID == IDC_CNTRTHRDPRIORITY ||
nID == IDC_DSPYTHRDPRIORITY);
DWORD dw;
//取对应该ID的焦点选项
CComboBox* pBox = (CComboBox*) GetDlgItem(nID);
int nCurSel = pBox- >GetCurSel();
switch (nCurSel)
{
case 0:
dw = (DWORD)THREAD_PRIORITY_IDLE;break;
case 1:
dw = (DWORD)THREAD_PRIORITY_LOWEST;break;
case 2:
dw = (DWORD)THREAD_PRIORITY_BELOW_NORMAL;break;
case 3:
default:
dw = (DWORD)THREAD_PRIORITY_NORMAL;break;
case 4:
dw = (DWORD)THREAD_PRIORITY_ABOVE_NORMAL;break;
case 5:
dw = (DWORD)THREAD_PRIORITY_HIGHEST;break;
case 6:
dw = (DWORD)THREAD_PRIORITY_TIME_CRITICAL;break;
}
if (nID == IDC_CNTRTHRDPRIORITY)
m_pCounterThread- >SetThreadPriority(dw);
//调整计数线程优先级
else
m_pDisplayThread- >SetThreadPriority(dw);
//调整显示线程优先级
}
这样线程优先级的调整只需要根据不同的ID来调用该函数:
void CMutexesDlg::OnSelchangeDspythrdpriority()
{ OnPriorityChange(IDC_DSPYTHRDPRIORITY);}
void CMutexesDlg::OnSelchangeCntrthrdpriority()
{ OnPriorityChange(IDC_CNTRTHRDPRIORITY);}
复选线程挂起的实现代码如下:
void CMutexesDlg::OnPause()
{
//取挂起复选框状态
CButton* pCheck = (CButton*)GetDlgItem(IDC_PAUSE);
BOOL bPaused = ((pCheck- >GetState() & 0x003) != 0);
if (bPaused) {
m_pCounterThread- >SuspendThread();
m_pDisplayThread- >SuspendThread();
}//挂起线程
else {
m_pCounterThread- >ResumeThread();
m_pDisplayThread- >ResumeThread();
}//恢复线程运行
}
---- 程 序 在::OnClose() 中 实 现 了 线 程 的 终 止。 在 本 例 程 当 中 对 线 程 的 终 止 稍 微 复 杂 些。 需 要 注 意 的 是 成 员 变 量m_bDone 的 作 用, 在 线 程 的 运 行 当 中 循 环 检 测 该 变 量 的 状 态, 最 终 引 起 线 程 的 退 出。 这 样 线 程 的 终 止 是 因 为 函 数 的 退 出 而 自 然 终 止, 而 非 采 用 强 行 终 止 的 方 法, 这 样 有 利 于 系 统 的 安 全。 该 程 序 中 使 用 了PostMessage 函 数, 该 函 数 发 送 消 息 后 立 即 返 回, 这 样 可 以 避 免 阻 塞。 其 实 现 的 代 码 为:

void CMutexesDlg::OnClose()
{
int nCount = 0;
DWORD dwStatus;
//取挂起复选框状态
CButton* pCheck = (CButton*) GetDlgItem(IDC_PAUSE);
BOOL bPaused = ((pCheck- >GetState() & 0x003) != 0);

if (bPaused == TRUE){
pCheck- >SetCheck(0);//复选取消
m_pCounterThread- >ResumeThread();
//恢复线程运行
m_pDisplayThread- >ResumeThread();
}

if (m_pCounterThread != NULL){
VERIFY(::GetExitCodeThread(m_pCounterThread- >
m_hThread, &dwStatus));//取计数线程结束码
if (dwStatus == STILL_ACTIVE){
nCount++;
m_pCounterThread- >m_bDone = TRUE;
}//如果仍为运行状态,则终止
else{
delete m_pCounterThread;
m_pCounterThread = NULL;
}//如果已经终止,则删除该线程对象
}

if (m_pDisplayThread != NULL){
VERIFY(::GetExitCodeThread(m_pDisplayThread- >
m_hThread, &dwStatus));//取显示线程结束码
if (dwStatus == STILL_ACTIVE){
nCount++;
m_pDisplayThread- >m_bDone = TRUE;
}//如果仍为运行状态,则终止
else{
delete m_pDisplayThread;
m_pDisplayThread = NULL;
}//如果已经终止,则删除该线程对象
}
if (nCount == 0)//两个线程均终止,则关闭程序
CDialog::OnClose();
else //否则发送WM_CLOSE消息
PostMessage(WM_CLOSE, 0, 0);
}
回复
legendhui 2005-05-24
---- 计 数 线 程::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();
//将字符串加入到列表框中
m_pOwner- >AddToListBox(strBuffer);
}//结束while
m_pOwner- >PostMessage(WM_CLOSE, 0, 0L);
return 0;
}

3在CMutexesDlg的头文件中加入如下成员变量:
CString m_strNumber;//线程所要操作的资源对象
CMutex m_mutex;//用于同步机制的互斥量
CCounterThread* m_pCounterThread;//指向计数线程的指针
CDisplayThread* m_pDisplayThread;//指向显示线程的指针
首先在对话框的初始化函数中加入如下代码对对话框进行初始化:
BOOL CMutexesDlg::OnInitDialog()
{
……
//初始化进程优先级组合框并置缺省为 NORMAL
CComboBox* pBox;
pBox = (CComboBox*) GetDlgItem(IDC_PRIORITYCLASS);
ASSERT(pBox != NULL);
if (pBox != NULL){
pBox- >AddString(_T("Idle"));
pBox- >AddString(_T("Normal"));
pBox- >AddString(_T("High"));
pBox- >AddString(_T("Realtime"));
pBox- >SetCurSel(1);
}
//初始化显示线程优先级组合框并置缺省为 NORMAL
pBox = (CComboBox*) GetDlgItem(IDC_DSPYTHRDPRIORITY);
ASSERT(pBox != NULL);
if (pBox != NULL){
pBox- >AddString(_T("Idle"));
pBox- >AddString(_T("Lowest"));
pBox- >AddString(_T("Below normal"));
pBox- >AddString(_T("Normal"));
pBox- >AddString(_T("Above normal"));
pBox- >AddString(_T("Highest"));
pBox- >AddString(_T("Timecritical"));
pBox- >SetCurSel(3);
}
//初始化计数线程优先级组合框并置缺省为 NORMAL
pBox = (CComboBox*) GetDlgItem(IDC_CNTRTHRDPRIORITY);
ASSERT(pBox != NULL);
if (pBox != NULL){
pBox- >AddString(_T("Idle"));
pBox- >AddString(_T("Lowest"));
pBox- >AddString(_T("Below normal"));
pBox- >AddString(_T("Normal"));
pBox- >AddString(_T("Above normal"));
pBox- >AddString(_T("Highest"));
pBox- >AddString(_T("Timecritical"));
pBox- >SetCurSel(3);
}
//初始化线程挂起复选框为挂起状态
CButton* pCheck = (CButton*) GetDlgItem(IDC_PAUSE);
pCheck- >SetCheck(1);
//初始化线程
m_pDisplayThread = (CDisplayThread*)
AfxBeginThread(RUNTIME_CLASS(CDisplayThread),
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
m_pDisplayThread- >SetOwner(this);

m_pCounterThread = (CCounterThread*)
AfxBeginThread(RUNTIME_CLASS(CCounterThread),
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
m_pCounterThread- >SetOwner(this);
……
}
然后填加成员函数:
void AddToListBox(LPCTSTR szBuffer);//用于填加列表框显示
该函数的实现代码为:
void CMutexesDlg::AddToListBox(LPCTSTR szBuffer)
{
CListBox* pBox = (CListBox*) GetDlgItem(IDC_DATABOX);
ASSERT(pBox != NULL);
if (pBox != NULL){
int x = pBox- >AddString(szBuffer);
pBox- >SetCurSel(x);
if (pBox- >GetCount() > 100)
pBox- >DeleteString(0);
}
}
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……