线程是一种从软件到硬件的技术,主要目的是为了提高运行速度,和多任务。

××××××××××××××××××××××××××××××××××××需要储备的资料(他人的)××××××××××××××××××××××××××××

××http://haobinnan.blog.51cto.com/775253/658446

多线程概述

进程和线程都是操作系统的概念。进程是在基于内存的概念,线程是基于CPU的概念。CPU不清楚什么玩意叫进程,CPU处理的任务叫线程。一个进程可以划分成多个线程给CPU处理。一个程序可以有多个进程 用于处理不同的事情。

进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。

线程是进程内部的一个执行单元,系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。

每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,所以线程间的通讯非常方便,多线程技术的应用也较为广泛。

MFC中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。

在MFC中,一般用全局函数AfxBeginThread()来创建并初始化一个线程的运行,该函数有两种重载形式,(为啥叫重载形式呢?因为系统中已经有了这两个函数,在使用的使用给予不同的变量不就是重载的定义吗??是的)分别用于创建工作者线程和用户界面线程。两种重载函数原型和参数分别说明如下:

CreateThread是一个API,而AfxBeginThread是MFC中的一个函数。后者在内部调用了前者。

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

 
    对于工作线程来说,启动一个线程,首先需要编写一个希望与应用程序的其余部分并行运行的函数如Fun1(),

接着定义一个指向CwinThread对象的指针变量*pThread,(在MFC中可以用App)

调用AfxBeginThread(Fun1,param,priority)函数,返回值付给pThread变量的同时一并启动该线程来执行上面的Fun1()函数,

其中Fun1是线程要运行的函数的名字,也既是上面所说的控制函数的名字,param是准备传送给线程函数 Fun1的任意32位值,

priority则是定义该线程的优先级别,它是预定义的常数。

线程函数是回调函数,线程函数在类内必须是静态成员函数,或者是类外声明的全局函数。

因为静态成员函数不能访问类的非静态成员函数,所以在线程函数中要定义一个类的指针指向this指针,就可以用类的指针来调用类的成员函数。

数据传递使用this处理。

HMI  WORK线程   

CWinThread* AfxBeginThread(

AFX_THREADPROC pfnThreadProc,//指向工作者线程的执行函数的指针,线程函数原型必须声明如下: UINTExecutingFunction(LPVOID pParam);

LPVOID pParam,/**///传递给线程函数的一个32位参数,执行函数将用某种方式解释该值。它可以是数值,或是指向一个结构的指针,甚至可以被忽略;

nPriority=THREAD_PRIORITY_NORMAL,//线程的优先级。如果为0,则线程与其父线程具有相同的优先级;

UINTnStackSize=0,//线程为自己分配堆栈的大小,其单位为字节。如果nStackSize被设为0,则线程的堆栈被设置成与父线程堆栈相同大小;

DWORDdwCreateFlags=0,//如果为0,则线程在创建后立刻开始执行。如果为CREATE_SUSPEND,则线程在创建后立刻被挂起;

LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL//线程的安全属性指针,一般为NULL;

);

一个工作线程创建的实例:
环境是VS2010  MFC  Win7  64位系统。

<span style="background-color: rgb(0, 204, 204);">public:
//工作线程创建第一步:在某个头文件里面声明一个函数。
static UINT Scada_Operational(LPVOID pParam);
int aaa;
}; extern CTestApp theApp;
</span>

×××

<span style="background-color: rgb(0, 204, 204);">//工作线程创建第二步:在对应的实现文件里面,定义这个函数。
UINT CTestApp::Scada_Operational(LPVOID pParam)
{
Sleep(1000);
AfxMessageBox(_T("准备赋值"));
CTestApp* theApp = (CTestApp*)pParam;
int bb=0; bb= theApp->aaa;
Sleep(1000);
AfxMessageBox(_T("完成赋值")); return 0;
}</span>

×××

<span style="background-color: rgb(0, 204, 204);">//工作线程创建第三步:使用MFC特有的函数AfxBeginThread 将函数变为线程。
AfxBeginThread(Scada_Operational,this);</span>

源代码:http://pan.baidu.com/s/1mgrAxVM
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

UI线程

创建一个用户界面线程,首先要从类CwinThread产生一个派生类,同时必须使用DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE来声明和实现这个CwinThread派生类。
  第二步是根据需要重载该派生类的一些成员函数如:ExitInstance();InitInstance();OnIdle(); PreTranslateMessage()等函数,最后启动该用户界面线程,调用AfxBeginThread()函数的一个版   本:

CWinThread*AfxBeginThread(

CRuntimeClass* pThreadClass,//从CWinThread派生的RUNTIME_CLASS类;

intnPriority=THREAD_PRIORITY_NORMAL,//线程优先级,如果为0,则与创建该线程的线程相同;

UINT nStackSize=0,//线程的堆栈大小,如果为0,则与创建该线程的线程相同;

DWORD dwCreateFlags=0,//一个创建标识,如果是CREATE_SUSPENDED,

则在悬挂状态创建线程,在线程创建后线程挂起,否则线程在创建后开始线程的执行。

LPSECURITY_ATTRIBUTESlpSecurityAttrs=NULL//线程的安全属性,NT下有用。

);

范例 :

1、建立一个基于MFC的对话框应用程序。
2、向程序中添加一个以CWinThread为基类的新类CUIThread,该类用于启动一个用户界面线程。
3、向程序中添加一个对话框资源,并建立相应的对话框类CUIThreadDlg,这个对话框的基类是CDialogEx。

该对话框将被作为用户界面线程的主窗口。
4、在UIThread.h中加入#include "UIThreadDlg.h"和 

public:
CUIThreadDlg m_dlg;

并在CUIThread::InitInstance()中加入

BOOL CUIThread::InitInstance()
{
// TODO: 在此执行任意逐线程初始化 //用户线程第六步:添加创建程序
m_pMainWnd = &m_dlg;
m_dlg.DoModal();
;
return TRUE;
}

5、CUIThread::InitInstance()中创建的CUIThreadDlg将与主窗口在独立的线程中运行,可以在CUIThreadDlg中加入各种执行耗时任务的代码而不会影响主窗口的运行。
6、在 原始对话框上面添加一个按钮 并创建点击事件响应函数,

//用户线程第七步:添加线程的头文件#include "UIThread.h"。

在函数中添加线程创建

void CTestGszDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//CWinThread* p = AfxBeginThread(RUNTIME_CLASS(CUIThread));
//用户线程第八步:正式创建线程
AfxBeginThread(RUNTIME_CLASS(CUIThread));
}

7:我们创建的线程在结束的时候 销毁我们新建的对话框

int CUIThread::ExitInstance()
{
    m_dlg.DestroyWindow();
    return CWinThread::ExitInstance();
}

配套源代码:http://pan.baidu.com/s/1jGzLTye

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

几个常用的配套函数

//获取线程对象

CWinThread* AFXAPIAfxGetThread();

//获取当前消息

MSG* AFXAPIAfxGetCurrentMessage();

//结束线程执行

void AFXAPIAfxEndThread(UINTnExitCode,BOOLbDelete =TRUE);

//初始化线程

void AFXAPIAfxInitThread();

//终止线程执行

void AFXAPIAfxTermThread(HINSTANCEhInstTerm =NULL);

在MFC里面实现线程的实例的更多相关文章

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

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

  2. MFC 多线程及线程同步

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

  3. java线程池实例

    目的         了解线程池的知识后,写个线程池实例,熟悉多线程开发,建议看jdk线程池源码,跟大师比,才知道差距啊O(∩_∩)O 线程池类 package thread.pool2; impor ...

  4. MFC 创建UI线程

    对于windows来说,所有的线程都是一样的,但MFC却把线程区分为两种:用户界面(UI)线程和工作者线程.用户界面线程具有消息循环而工作者线程没有.UI线程可以创建窗口并给这些窗口发送消息,工作者线 ...

  5. 深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)

    1.创建和终止线程 在MFC程序中创建一个线程,宜调用AfxBeginThread函数.该函数因参数不同而具有两种重载版本,分别对应工作者线程和用户接口(UI)线程. 工作者线程 CWinThread ...

  6. MFC在子线程中创建窗口(PostMessage方法)

    1.创建子线程 C++创建线程的方式比较多 1)最简单易用的<thread>头文件,但是这种方法创建的子线程中无法给主线程PostMessage消息(也可能是我操作有误,总之没成功) 2) ...

  7. Java线程基础实例

    概述 Java线程是一个在实战开发中经常使用的基础功能,而在Java中线程相关的类在java.lang和java.util.concurrent里 Thread package thread.base ...

  8. 简单的C#线程开发实例(隔一秒改变一下Label的Text)

    要实现的效果:点击按纽,窗口上的label上出现1~100数字的变化. 第一个实例(把窗口上的label上文字改成0): using System; using System.Windows.Form ...

  9. Java5中的线程池实例讲解

    Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活.本文通过一个网络服务器模型,来实践Java5的多线程 ...

随机推荐

  1. 【BZOJ】2179: FFT快速傅立叶(fft)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2179 fft裸题.... 为嘛我的那么慢....1000多ms.. #include <cst ...

  2. JAVA基础之訪问控制权限(封装)

    包:库单元 1.当编写一个Java源码文件时.此文件通常被称为编译单元(有时也被称为转译单元). 2.每一个编译单元都必须有一个后缀名.java,而在编译单元内则能够有一个public类,该类名称必须 ...

  3. 验证:record项元的多少影响修改速度。

    验证erlang官网提供的思想:record的修改是复制. -module (test_record). -record (record_5,{ aa1 = 0, aa2 = 0, aa3 = 0, ...

  4. Thinkphp整合各个功能

    thinkphp整合Auth权限管理.支付宝.微信支付.阿里oss.友盟推送.融云即时通讯.云通讯短信.Email.Excel.PDF等等: 基于thinkphp扩展了大量的功能:而不改动thinkp ...

  5. db2 improt from coldel0x7c

    db2 load from "C:\20110816\20110816_BankEnterpri seCA.txt" OF del modified by coldel0x7c r ...

  6. 【MongoDB】嵌套数组查询方案

    From:http://stackoverflow.com/questions/12629692/querying-an-array-of-arrays-in-mongodb 数据 db.multiA ...

  7. Effective C++ Item 10,11 Have assignment operators return a reference to *this Handle assignment to self in operator =

    If you want to concatenate assignment like this int x, y, z; x = y = z = 15; The convention is to ma ...

  8. 编程之美 set 18 拈两堆石子游戏(3)

    题目 假设有两堆石头, 有两个玩家按照如下规则轮流取石头 每个人每次可以从两堆石头中取出数量相等的石头, 或者仅从一堆石头中取出任意数量的石头 最后把剩下的石头依次拿光的人取胜 首先取石头的人能否赢得 ...

  9. studio导入Eclipse 项目要改的文件

    添加下面文件即可,一个不能少 1. project 2.project.properties 3.classpath 4.AndroidManifest.xml 以上目录都有可以正常导入studio中

  10. Spring中bean的作用范围

    singleton作用域: Spring的scope的默认值是singleton Spring 只会为每一个bean创建一个实例,并保持bean的引用. <bean id="bean的 ...