[普通]MFC多线程概述

作者(passion) 阅读(976次) 评论(0) 分类( c++)

上一节我们使用过多线程,但是采用的并不是MFC独有的多线程,这两节课程我们就简单的说一下MFC的多线程。

MFC中,线程分为两种,一种是用户接口线程,或称用户界面线程,另一种是工作线程,这两种线程可以满足不同的任务的处理需求。

1.用户接口线程

用户接口线程通常用来处理用户输入产生的消息和事件,并独立的响应正在应用程序其他部分执行的线程产生的消息和事件,MFC特别地为用户接口线程提供了一个消息泵。用户接口线程包含一个消息处理的循环,以应对各种事件。

CWinApp类的对象就是一个用户接口线程的典型例子。在生成基于MFC的应用程序的时候,它的主线程就已经创建了,并随着应用程序的执行而投入运行。基于MFC的应用程序都有一个应用对象,它是CWinApp派生类的对象,该对象就代表了应用程序进程的主线程,负责处理用户输入以及其他的各种事件和相应的消息。

如果应用程序具有多个线程,而每个线程中都有用户接口,那么使用MFC的用户接口线程来编程就特别的方便。

MFC应用程序中,所有的线程都是有CWinThread对象来表示的。CWinThread类是用户接口线程的基类,CWinApp就是从CWinThread类派生出来的,在编写用户接口线程的时候,也需要从CWinThread类派生出自己的线程来,借助ClassWizard可以很容易的做这项工作。

2.工作线程

工作线程适用于处理那些不要求用户输入并且比较消耗时间的其他任务,如大规模的重复计算,网络数据的发送和接收,以及后台打印等。对用户来说,工作线程运行在后台。这就使得工作线程特别适合去等待一个事件的发生。例如,应用程序要接收网络上服务器发来的数据,但由于种种原因数据迟迟不能到达,接收方必须堵塞等待,如果把这种任务交给工作线程来做,他就可以在后台等待,并不影响前台用户接口线程的运行。用户不必等待这些后台任务的完成,用户的输入仍然能得到及时的处理。在网络编程中,凡是可能引起系统堵塞的操作,都可以用工作线程来完成。

CWinThread类同样是工作线程的基类,同样是由CWinThread对象来表示的。但在编写工作线程的时候,甚至不必刻意地从CWinThread类派生出自己的线程类对象。用户可以调用MFC框架的AfxBeginThread函数来创建CWinThread对象。

创建MFC的工作线程

创建一个工作线程是一个相对简单的任务,只要经过两个步骤就能是工作线程运行:第一步是编程实现控制函数,第二步是创建并启动工作线程,一般不必从CWinThread派生一个类。当然,如果需要一个特定版本的CWinThread类,也可以去派生,但对于大多数的工作线程是不要求的,可以不做任何修改地使用CWinThread


1.编程实现控制函数

一个工作线程对应一个控制函数。线程执行的任务都应编写在控制函数之中。控制函数规定了该线程的执行代码,所谓启动线程,实际就是开始运行它对应的控制函数,当控制函数执行结束而退出时,线程也就随之终止。编写实现工作线程的控制函数是创建工作线程的第一步。编写工作线程的控制函数必须遵守一定的格式。

2.创建并启动工作线程

在进程的主线程或其他线程中调用AfxBeginThread函数就可以创建新的线程,并使新线程开始执行。一般将线程的创建者成为新线程的父线程。

AfxBeginThread函数是MFC提供的帮助函数,有两个重载的版本,区别在于使用的入口参数不同。一个用于创建并启动用户接口线程,一个用于创建并启动工作线程。

在创建一个工作线程之前,不需要自己去创建CWinThread对象,调用AfxBeginThread函数执行时,会使用用户提供的上述参数,为用户创建并初始化一个新的CWinThread类的线程对象,为它分配相应的资源,建立相应的数据结构,然后自动调用CWinThread类的CreateThread函数开开始执行这个线程,并返回指向此CWinThread编程对象的指针。利用这个指针,可以调用CWinThread来的其他成员函数来管理这个线程

3.创建工作线程的例子

    1.编程实现线程控制函数。

C++

Struct tagData{
    Int n;
    Double * pD;};
 tagData   m_Data;  
UINT MyThreadProc(LPVOID pParam){
    If( pParam == NULL ) AfxEndThread(MY_NULL_POINTER_ERROR);  
    tagData  *pData = (tagData*) pParam;
     
    ...
     
    return 0;}

2.在程序进程的主线程中调用AfxBeginThread函数来创建并启动运行这个线程。将控制函数名和结构变量的地址作为参数来传递,其他的参数省略,表示使用默认值。

C++

AfxBeginThread(MyThreadProc,&Data);

一旦调用了此函数,线程就被创建,并开始执行线程函数。当数据的计算完成时,函数将停止运行,相应的线程也随之终止。线程拥有的推展和其他资源都将释放。CWinThread对象将被删除。

4.创建工作线程的一般模式

从上面的例子中可以得出创建工作线程的一般模式,具有如下

1.工作线程控制函数的框架

C++

UINT MyFunProc(LPVOID pParam){
    CMyObject*pObject = (CMyObject*)pParam;
     
    if( pObject == NULL || !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)) )
        return 1;
     
    return 0;}

2.在程序的另一个函数中插入以下代码

C++

pNewObject = new CMyObject;AfxBeginThread(MyThreadProc,pNewObject);

下一节我们在说一下用户界面线程


« 上一篇:wifi共享上网(至尊版wifi)
« 下一篇:drcom至尊版使用openwrt路由器拨号
在这里写下您精彩的评论
  • 微信

  • QQ

  • 支付宝

返回首页
返回首页 img
返回顶部~
返回顶部 img