最近学习了MFC多线程的使用,

写了一个继承CWinThread类的类MyThread;

在头文件开头用#define定义一个线程函数入口地址(会在下面定义代码中写出)

在类的开头加上IMPLEMENT_DYNCREATE(MyThread, CWinThread)

继承的子类里面必须重写两个函数

一、virtual BOOL InitInstance();
二、virtual int ExitInstance();

声明一个线程函数,函数名自定,我的类中的线程函数叫StartThread

在声明完线程函数后再声明DECLARE_MESSAGE_MAP(),该函数包含了消息映射必要的函数,声明了它就相当于在类内声明了这些提供消息映射必要的函数。

头文件中类定义如下:

#ifndef T_THREAD_H
#define T_THREAD_H
#pragma once
#define WM_TEST WM_USER + 105 //定义线程函数入口地址
class mythread1 : public CWinThread
{
DECLARE_DYNCREATE(MyThread)
public:
MyThread();
virtual BOOL InitInstance();
virtual int ExitInstance();
void StartThread(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP();
};
#endif

然后在CPP文件开头加上IMPLEMENT_DYNCREATE(MyThread, CWinThread)

这样做的意图在于使能Cobject派生类的对象在运行时动态被创建。

然后在重写了

BOOL InitInstance();

int ExitInstance();

两个函数的定义后,在定义线程函数时加上下面的语句

BEGIN_MESSAGE_MAP(MyThread, CWinThread)
    ON_THREAD_MESSAGE(WM_TEST, StartThread)
END_MESSAGE_MAP()

这三条代码的作用是将线程消息传递路由定义好

关于这三条语句以及类中声明的消息映射函数我是参考这篇博客https://blog.csdn.net/luoti784600/article/details/10070939

cpp代码如下

#include "stdafx.h"
#include "t_thread.h"
IMPLEMENT_DYNCREATE(MyThread, CWinThread) MyThread::MyThread()
{ } BOOL MyThread::InitInstance()
{
return true;
}
int MyThread::ExitInstance()
{
return 0;
}
BEGIN_MESSAGE_MAP(MyThread, CWinThread)
ON_THREAD_MESSAGE(WM_TEST, StartThread)
END_MESSAGE_MAP()
void mythread1::StartThread(WPARAM wParam, LPARAM lParam)
{
while (true)
{
TRACE("2\n");
Sleep(1000);
}
::AfxEndThread(2015);
}

在线程内调用AfxEndThread将会直接结束线程,此时线程的一切资源都会被回收,函数的参数是nExitCode,可以通过GetExitCodeThread获得。

然后按键消息函数中开启线程,开启线程的方式是先声明定义一个线程类指针

MyThread* p_MyThread;

再用AfxBeginThread获得线程指针

p_MyThread= (MyThread*)AfxBeginThread(RUNTIME_CLASS(MyThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

AfxBeginThread有两种重载函数定义,一种叫工作线程,一种叫用户界面线程,通过输入参数的不同区别,本例中使用的是用户界面线程,

关于AfxBeginThread两种函数定义的介绍,可以参考https://blog.csdn.net/MissXy_/article/details/80330263

按键消息函数内代码如下:

void CmythreadDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码 p_MyThread= (MyThread*)AfxBeginThread(RUNTIME_CLASS(MyThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
p_MyThread->ResumeThread();
p_MyThread->PostThreadMessage(WM_TEST, NULL, NULL);
display();
}
void CmythreadDlg::display()
{
while (1)
{
TRACE("1\n");
Sleep(1000);
}
}

本例的意图是用两个线程,分别打印出1,2两个数字。

运行结果如下:

记录完毕,欢迎指出不足!

MFC多线程的创建使用的更多相关文章

  1. MFC 多线程

    MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息   队列和消息循环. 工作者线程没有消息机制,通 ...

  2. MFC多线程内存泄漏问题&解决方法

    在用visual studio进行界面编程时(如MFC),前台UI我们能够通过MFC的消息循环机制实现.而对于后台的数据处理.我们可能会用到多线程来处理. 那么对于大多数人(尤其是我这样的菜鸟),一个 ...

  3. Win32 多线程的创建方法和基本使用

    Win32多线程的创建方法主要有: (1)CreateThread() (2)_beginthread()&&_beginthreadex() (3)AfxBeginThread() ...

  4. MFC多线程各种线程用法 .

    http://blog.csdn.net/qq61394323/article/details/9328301 一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleTh ...

  5. MFC多线程详细讲解(转)

    一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...

  6. iOS开发多线程篇—创建线程

    iOS开发多线程篇—创建线程 一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 创建.启动线程 (1) NSThread *thread = [[NSThread alloc] in ...

  7. MFC应用程序创建窗口的过程 good

    MFC应用程序中处理消息的顺序 1.AfxWndProc()      该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc()  该 ...

  8. Python多线程的创建,相关函数和守护线程的理解

    一:多线程的创建 threading库创建线程有两种方式,函数式和继承式    1)函数式 def func(): print 'Starting' print 'Ending' t=threadin ...

  9. 深入浅出MFC——MFC多线程程序设计(七)

    1. 从操作系统层面看线程——三个观念:模块(MDB).进程(PDB).线程(TDB) 2. “执行事实”发生在线程身上,而不在进程身上.也就是说,CPU调度单位是线程而非进程.调度器据以排序的,是每 ...

随机推荐

  1. vue中改变数组或对象,页面没做出对应的渲染

    原文链接 数组更新检测 变异方法 Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新.这些方法如下: push() pop() shift() unshift() splice() sor ...

  2. luoguP5024 保卫王国

    题目链接 问题分析 其实是比较明显的动态DP. 懒于再推一遍式子,直接用 最小权点覆盖=全集-最大权独立集,然后就和这道题一样了.题解可以看这里. 然后必须选或者不选的话,就直接把相应的点权变成\(- ...

  3. win7安装Elasticsearch和Elasticsearch-Head插件

    1.环境搭建 1)Java环境搭建可以参考相关的资料,这里不做详细介绍 2)nodejs环境搭建 到官方网站下载相应的zip包:https://nodejs.org/dist/v8.9.1/node- ...

  4. zookeeper系列(二)zookeeper的使用--javaAPI

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败: 出处:http://www.cnblogs.com/leesf456/ (尊重原创,感谢作者整理的这么好,作者的部分内容添加了我的理解 ...

  5. 编译型语言VS解释型语言

  6. OUC_Summer Training_ DIV2_#9 719

    其实自己只会做很简单的题,有时都不想写解题报告,觉得不值得一写,但是又想到今后也许就不会做ACM了,能留下来的东西只有解题报告了,所以要好好写,很渣的题也要写,是今后的纪念. B - B Time L ...

  7. spark streaming 6: BlockGenerator、RateLimiter

    BlockGenerator和RateLimiter其实很简单,但是它包含了几个很重要的属性配置的处理,所以记录一下. ))) , SECONDS) From WizNote

  8. mvp解读

    mvp存在的问题 1.业务复杂时,可能使得Activity变成更加复杂,比如要实现N个IView,然后写更多个模版方法. 2.业务复杂时,各个角色之间通信会变得很冗长和复杂,回调链过长. 3.Pres ...

  9. android手机使用Fiddler

    Fiddler是一款免费的抓包.调试工具,比Wireshark要小巧,更简洁,这里介绍如何通过WIFI来抓取Android手机的HTTP和HTTPS包. 一.手机端配置 电脑配置WIFI后,手机需要设 ...

  10. MongoDB数据节点基础操作

    1.查看集群中各节点的状态: rs0:PRIMARY> rs.status() 2.查看集群中各节点配置情况: rs0:PRIMARY> rs.conf() 3.主节点降级为从节点: rs ...