什么时候该使用多线程

什么时候该使用多线程,以及更恰当的多线程编程方法之讨论

大约在写了一年左右的应用程序以后开始发生了一些困惑,在我写的程序中很多使用了多线程,我们了解使用线程的必要性,但是什么时候使用,以及该如何更好使用和管理多线程方面,我觉得值得思考。

先讨论一下CApp类的实质。App就是一个用户界面线程。

众所周知,CApp类继承于CWinThread类,是一个线程类,它的实例就是应用程序的主线程(一个用户界面线程)。App 实例化一个WinThread以后,主要的工作就是维护一个消息循环,直到收到程序退出消息,退出循环并终止线程。

可见App对象使一个线程具有了处理消息的能力,而线程本身并没有这个能力,(了解这一点的目的在于弄清楚线程消息的概念。)拥有这种能力的线程也就是用户界面线程。

一个线程就是一个代码的执行路径,如果没有App那么线程将按照一个固定的路径执行代码,不会受到任何外界情况的干扰(除非是CPU掉电,或者发生了硬件中断)。显然这不是我们想要看到的,于是如何控制一个线程的运行便成为了一个需要解决的问题,操作系统大多采用了消息机制的解决方案。所谓的消息是一种抽象的概念,其实就是一个操作系统的数据结构,一个可以被App主线程消息循环函数接受的参数。有了消息还不够,还必须要有发送消息的对象。这个对象一般是窗口,窗口作为用户界面线程的一部分用以接受各种事件,事件发生以后,窗口线程就向(自己)线程的消息队列里发送事件所对应的消息。消息的发出者还可以是主线程的其它子线程,也可以是主线程自身(窗口),当然也可以使操作系统。了解了消息机制的原理以后可以对我们编程提供一些帮助,比如,App主线程中不应该执行耗时很长的代码(比如循环,或者I/O操作,或者运算量很大的代码),这样才不会阻塞消息循环,导致界面“死掉”。 解决这个问题的方案就是创建子(辅助)线程来完成这些任务。

这里要指出的几点是:(注:以下所说的子线程皆指辅助线程,而非界面线程)

1.主线程不可以向子线程发送消息(但是反之则可以),这种做法本身没有任何意义,是概念不清的问题;

2.当窗口要向子线程发送消息时;这个问题也是本文讨论的重点。首先,子线程没有处理消息的能力,它只能按照原先设定好的路径运行。所以窗口只能将消息发送给主线程,再由主线程想办法改变子线程的行为。主线程如何跟子线程通讯呢?(显然不能用消息)我所能想到的就是主线程改变一些公共域的值,然后由子线程通过轮训的方式来实现通讯。这也是windows给我们提供的方法,当我们使用AfxBeginThread或者CreateThread创建一个子线程的时候,会传入一个对象的指针,很显然,这个对象就是控制子线程的关键。

至此了解了什么时候使用多线程的问题。

第2个问题:如何更好的使用多线程

首先是代码结构的问题。我们可以将子线程所要完成的功能全部在一个线程函数里实现,这显然在大多数时候是不合理的,第二种方法是通过父线程传递来的对象指针,调用该对象类的成员函数来实现所需的功能。这里引发新的问题,需不需要单独创建一个类来包装这些函数,还是将这些函数写在父线程的类中(包括辅助线程处理函数自己)。这两种方法从本质上来说似乎没有什么差别。后者的话,当我们需要改变子线程的行为时,只需要改变自身类成员变量就可以了,但是结构显得有些混乱。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值