什么时候该使用多线程,以及更恰当的多线程编程方法之讨论
2006-07-21 16:14
841 查看
大约在写了一年左右的应用程序以后开始发生了一些困惑,在我写的程序中很多使用了多线程,我们了解使用线程的必要性,但是什么时候使用,以及该如何更好使用和管理多线程方面,我觉得值得思考。
先讨论一下CApp类的实质。App就是一个用户界面线程。
众所周知,CApp类继承于CWinThread类,是一个线程类,它的实例就是应用程序的主线程(一个用户界面线程)。App 实例化一个WinThread以后,主要的工作就是维护一个消息循环,直到收到程序退出消息,退出循环并终止线程。
可见App对象使一个线程具有了处理消息的能力,而线程本身并没有这个能力,(了解这一点的目的在于弄清楚线程消息的概念。)拥有这种能力的线程也就是用户界面线程。
一个线程就是一个代码的执行路径,如果没有App那么线程将按照一个固定的路径执行代码,不会受到任何外界情况的干扰(除非是CPU掉电,或者发生了硬件中断)。显然这不是我们想要看到的,于是如何控制一个线程的运行便成为了一个需要解决的问题,操作系统大多采用了消息机制的解决方案。所谓的消息是一种抽象的概念,其实就是一个操作系统的数据结构,一个可以被App主线程消息循环函数接受的参数。有了消息还不够,还必须要有发送消息的对象。这个对象一般是窗口,窗口作为用户界面线程的一部分用以接受各种事件,事件发生以后,窗口线程就向(自己)线程的消息队列里发送事件所对应的消息。消息的发出者还可以是主线程的其它子线程,也可以是主线程自身(窗口),当然也可以使操作系统。了解了消息机制的原理以后可以对我们编程提供一些帮助,比如,App主线程中不应该执行耗时很长的代码(比如循环,或者I/O操作,或者运算量很大的代码),这样才不会阻塞消息循环,导致界面“死掉”。 解决这个问题的方案就是创建子(辅助)线程来完成这些任务。
这里要指出的几点是:(注:以下所说的子线程皆指辅助线程,而非界面线程)
1.主线程不可以向子线程发送消息(但是反之则可以),这种做法本身没有任何意义,是概念不清的问题;
2.当窗口要向子线程发送消息时;这个问题也是本文讨论的重点。首先,子线程没有处理消息的能力,它只能按照原先设定好的路径运行。所以窗口只能将消息发送给主线程,再由主线程想办法改变子线程的行为。主线程如何跟子线程通讯呢?(显然不能用消息)我所能想到的就是主线程改变一些公共域的值,然后由子线程通过轮训的方式来实现通讯。这也是windows给我们提供的方法,当我们使用AfxBeginThread或者CreateThread创建一个子线程的时候,会传入一个对象的指针,很显然,这个对象就是控制子线程的关键。
至此了解了什么时候使用多线程的问题。
第2个问题:如何更好的使用多线程
首先是代码结构的问题。我们可以将子线程所要完成的功能全部在一个线程函数里实现,这显然在大多数时候是不合理的,第二种方法是通过父线程传递来的对象指针,调用该对象类的成员函数来实现所需的功能。这里引发新的问题,需不需要单独创建一个类来包装这些函数,还是将这些函数写在父线程的类中(包括辅助线程处理函数自己)。这两种方法从本质上来说似乎没有什么差别。后者的话,当我们需要改变子线程的行为时,只需要改变自身类成员变量就可以了,但是结构显得有些混乱。
先讨论一下CApp类的实质。App就是一个用户界面线程。
众所周知,CApp类继承于CWinThread类,是一个线程类,它的实例就是应用程序的主线程(一个用户界面线程)。App 实例化一个WinThread以后,主要的工作就是维护一个消息循环,直到收到程序退出消息,退出循环并终止线程。
可见App对象使一个线程具有了处理消息的能力,而线程本身并没有这个能力,(了解这一点的目的在于弄清楚线程消息的概念。)拥有这种能力的线程也就是用户界面线程。
一个线程就是一个代码的执行路径,如果没有App那么线程将按照一个固定的路径执行代码,不会受到任何外界情况的干扰(除非是CPU掉电,或者发生了硬件中断)。显然这不是我们想要看到的,于是如何控制一个线程的运行便成为了一个需要解决的问题,操作系统大多采用了消息机制的解决方案。所谓的消息是一种抽象的概念,其实就是一个操作系统的数据结构,一个可以被App主线程消息循环函数接受的参数。有了消息还不够,还必须要有发送消息的对象。这个对象一般是窗口,窗口作为用户界面线程的一部分用以接受各种事件,事件发生以后,窗口线程就向(自己)线程的消息队列里发送事件所对应的消息。消息的发出者还可以是主线程的其它子线程,也可以是主线程自身(窗口),当然也可以使操作系统。了解了消息机制的原理以后可以对我们编程提供一些帮助,比如,App主线程中不应该执行耗时很长的代码(比如循环,或者I/O操作,或者运算量很大的代码),这样才不会阻塞消息循环,导致界面“死掉”。 解决这个问题的方案就是创建子(辅助)线程来完成这些任务。
这里要指出的几点是:(注:以下所说的子线程皆指辅助线程,而非界面线程)
1.主线程不可以向子线程发送消息(但是反之则可以),这种做法本身没有任何意义,是概念不清的问题;
2.当窗口要向子线程发送消息时;这个问题也是本文讨论的重点。首先,子线程没有处理消息的能力,它只能按照原先设定好的路径运行。所以窗口只能将消息发送给主线程,再由主线程想办法改变子线程的行为。主线程如何跟子线程通讯呢?(显然不能用消息)我所能想到的就是主线程改变一些公共域的值,然后由子线程通过轮训的方式来实现通讯。这也是windows给我们提供的方法,当我们使用AfxBeginThread或者CreateThread创建一个子线程的时候,会传入一个对象的指针,很显然,这个对象就是控制子线程的关键。
至此了解了什么时候使用多线程的问题。
第2个问题:如何更好的使用多线程
首先是代码结构的问题。我们可以将子线程所要完成的功能全部在一个线程函数里实现,这显然在大多数时候是不合理的,第二种方法是通过父线程传递来的对象指针,调用该对象类的成员函数来实现所需的功能。这里引发新的问题,需不需要单独创建一个类来包装这些函数,还是将这些函数写在父线程的类中(包括辅助线程处理函数自己)。这两种方法从本质上来说似乎没有什么差别。后者的话,当我们需要改变子线程的行为时,只需要改变自身类成员变量就可以了,但是结构显得有些混乱。
相关文章推荐
- vba编程不知道该使用什么对象属性方法实现操作的时候用宏录制来查阅代码
- [转载]讨论下静态方法 非静态方法的区别,以及在什么时候使用
- MFC中使用boost::bind进行多线程编程的一种方法
- VC6 STL使用时候很多warning, stl使用以及消除warning的方法如下
- 多线程出现脏读以及解决方法(使用synchronized)
- 网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别?
- 多线程中join方法的使用方法以及其特点
- 在SharePoint中服务器端使用Word编程模型转换PDF遇到的问题以及解决方法
- 【读后感】hashcode和equals方法。 以及捎带提提String使用equals方法和==分别比较的是什么?
- java多线程编程之使用Synchronized关键字同步类方法
- 谈谈JavaScript中编程实现以及使用内置方法实现进制转换
- Vickate_多线程的小方法以及如何使用多线程解决同步请求图片的卡顿现象
- QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )
- 多线程编程之重点--使用DSP/BIOS时选择线程类型的参考方法
- 001_你使用过Objective-C的运行时编程(Runtime Programming)么?如果使用过,你用它做了什么?你还能记得你所使用的相关的头文件或者某些方法的名称吗?
- iPhone SDK中多线程的使用方法以及注意事项
- 在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环?
- 什么是H标签?H1,H2,H3标签?以及和strong标签使用的方法及重要性
- iPhone SDK中多线程的使用方法以及注意事项
- 编程小技巧:使用GDI32函数安装字体,以及.NET中的方法