




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在BCB中使用多线程实例2013-07-26 | 分类: 编程总结 | 标签:bcb 线程 | 浏览(1000)多线程编程是提高系统资源利用率的一种常见方式。它占用的资源更小,启动更快,还可以实现在后台运行一些需时较长的操作。喝小酒的网摘/a/8498.htm一、初识TThread对象VCL提供了用于多线程编程的TThread类,在这个类中封装了Windows关于线程机制的Windows API,通常将它的实例成为线程对象。线程对象通过封装简化了多线程应用程序的编写。注意,线程对象不允许控制线程堆栈的大小或安全属性。若需要控制这 些,必须使用Windows API的CreateThread()或BeginThread()函数。不过,即使是使用Windows Thread API函数建立和控制多线程,仍然可从一些同步线程对象或下节将要描述的方法中受益。要在应用程序中使用线程对象,必须创建TThread的一个派生类。File|New|Thread Object,系统会提示为新线程对象提供类名,我们将其命名为TMyThread。我们必须自行在构造函数以及Execute()函数中添加代码。自动 生成的构造函数中有一个参数,如果为true的话线程创建后将进入挂起状态,直到线程对象的Resume()函数被调用才开始执行。如果为false则线 程创建后会立刻开始执行。我们先创建一个实例来亲自感受下多线程:在窗体上放两个Button和两个Edit组件,自动命名。然后File|New|Thread Object来创建一个线程对象,命名为TMyThread。以下请看完整工程代码:/Unit1.h /主窗体头文件/-#ifndef Unit1H#define Unit1H/-#include #include #include #include #include Unit2.h/-class TForm1 : public TForm_published: / IDE-managed ComponentsTButton *Button1;TButton *Button2;TEdit *Edit1;TEdit *Edit2;void _fastcall Button1Click(TObject *Sender);void _fastcall Button2Click(TObject *Sender);void _fastcall FormCreate(TObject *Sender);private: / User declarationsTMyThread *thread1,*thread2;public: / User declarations_fastcall TForm1(TComponent* Owner);/-extern PACKAGE TForm1 *Form1;/-#endif/Unit1.cpp /主窗体实现文件/-#include #pragma hdrstop#include Unit1.h/-#pragma package(smart_init)#pragma resource *.dfmTForm1 *Form1;/-_fastcall TForm1:TForm1(TComponent* Owner): TForm(Owner)/-void _fastcall TForm1:Button1Click(TObject *Sender)thread1-Resume(); /单击后才启动线程/-void _fastcall TForm1:Button2Click(TObject *Sender)thread2-Resume();/-void _fastcall TForm1:FormCreate(TObject *Sender)thread1=new TMyThread(true,Edit1); /创建线程对象实例thread2=new TMyThread(true,Edit2);/-/Unit2.h /线程类头文件/-#ifndef Unit2H#define Unit2H/-#include /-class TMyThread : public TThread private:TEdit *edResult; /自定义局部变量String strResult;protected:void _fastcall Execute();void _fastcall ShowResult(); /自定义函数public:_fastcall TMyThread(bool CreateSuspended,TEdit *AEdit); /注意:修改了默认参数;/-#endif/Unit2.cpp /线程类实现文件/-#include #pragma hdrstop#include Unit2.h#pragma package(smart_init)/-_fastcall TMyThread:TMyThread(bool CreateSuspended,TEdit *AEdit): TThread(CreateSuspended)edResult=AEdit;/-void _fastcall TMyThread:Execute()for(int i=0;iText=strResult;/-然后我们F9运行程序就可以查看效果了。二、编写线程函数Execute()函数就是线程函数,它包含了程序中所有需要并行执行的代码。除了共享相同的进程空间外,可以认为线程就是通过应用程序启动的程序。但在 编写线程函数的时候需要注意与单独程序的不同之处。因为线程与其他线程共享内存空间,所以必须确认没有覆盖应用程序中其它线程的内存地址。而另一方面,可 以使用共享内存在线程之间进行通信。在线程函数内部,我们可以使用任意的全局变量,但有些变量我们并不希望同一线程类的其他实例共享它,就可以声明一个线程(thread-local)变 量。通过将_thread修饰语加入变量声明就可以声明一个线程变量。例如 int _thread x; 声明一个整型变量。_thread修饰语只可用于全局(文件范围)或静态变量。指针和函数变量不能作为线程变量。使用“在写入时复制”语法的类,如AnsiStrings也不能作为线程变量。需要在运行时进行初始化或析构的类型也不能被声明为_thread类型。当程序中调用Resume()函数时,线程启动并继续执行直到Execute()结束。这就是线程执行特定任务,并在其完成时终止的模式。然而,有时应用 程序需在一些外部条件满足时终止线程。通过检查Terminated属性可允许其它线程通知本线程终止。当其它线程试图终止本线程时,它调用 Terminate()函数。Terminate()函数将本线程的Terminated属性设置为true。Execute()函数通过检查和响应 Terminated属性来实现Terminate()函数。下面的实例演示了这种做法:void _fastcall TMyThread:Execute()while( !Terminated )在线程函数终止时我们可能需要做一些清理工作。由于在线程终止前,OnTerminate事件会发生,所以我们可以将清理代码放在OnTerminate 事件处理程序中,这样可确保不管Execute()函数如何执行,清理代码总是可以被执行。要注意OnTerminate事件处理程序不作为线程的一部分 运行,而是在应用程序的主线程中执行的。这意味着:(1)在OnTerminate事件处理程序中不能使用任何线程局部变量。(2)在OnTerminate事件处理程序中可安全地访问任何组件及VCL对象而不会和其他线程发生冲突。三、协调线程在编写线程执行时运行的代码时,必须考虑到可能同步执行的其他线程行为。主要有两种情况:一个是避免两个线程试图同时使用某一个全局对象或变量;另一个是某线程中的一些代码可能会依赖其他线程所执行任务的结果。1,避免同时访问为避免在访问全局对象或变量时与其他线程发生冲突,可能需要暂停其他线程的执行,直到该线程代码完成操作。这里需要注意,不要暂停其他不需停止的线程执行,这样会使效率严重降低,也无法获得使用多线程的优点。,锁定对象一些对象内置了锁定功能,以防止其他线程使用该对象的实例。例如,画布对象(TCanvas及其派生类)有一种Lock()函数可防止其他线程访问画布,直到调用Unlock()函数。VCL还包含一种线程安全的列表对象TThreadList。调用TThreadList:LockList()返回列表对象,同时组织其他线程使用列 表直到调用UnlockList()函数。调用TCanvas:Lock()函数或TThreadList:LockList()函数时可以安全地嵌 套。锁定直到最后一个锁定调用匹配到同一线程中相应的解锁调用时才会被释放。显然这种方法只对部分类有效。,使用重要区段若对象没有提供内置的锁定功能,可使用重要区段。重要区段像门一样,每次只允许一个线程进入。要使用它,需创建TCriticalSection的全局实 例。TCriticalSection有两个函数:Acquire()(阻止其他线程执行该区段)以Release()(取消对其他线程的阻止)。每个重要区段都与需要保护的全局内存关联。每个要访问这个全局内存的线程首先要调用Acquire()函数以确保其他线程不能访问它。当线程结束时,要调用Release()函数以便其他线程能继续访问。例如,应用程序有一个全局重要区段变量pLockXY,可阻止访问全局变量X和Y。任何使用X或Y的线程必须调用重要区段,如下所示:pLockXY-Acquire();tryY=sin(X);_finallypLockXY-Release();,使用多重读、独占写的同步器当使用重要区段来保护全局内存时,每次只有一个线程可以使用该内容。这种保护可能超出了需要,特别是当有一个经常读但很少写的对象或变量时更是如此。多个 线程同时读相同内存但没有线程写内存是没有危险的。当有一些经常被读但很少有线程向其写入的全局内存时,可使用 TMultiReadExclusiveWriteSynchronizer对象保护它。这个对象与重要区段一样,但它允许多个线程同时读,只要没有线程 写即可。线程必须有独占访问权才能写使用TMultiReadExclusiveWriteSynchronizer保护的内存。要使用“多重读、独占写”的同步器,需创建TMultiReadExclusiveWriteSynchronizer的一个全局实例,它与要保护的全局 内存关联。每个需要读内存的线程首先要调用BeginRead()函数。它确保当前无其它线程写内存。线程完成读操作后调用EndRead()函数。任何 线程要写内存的时候必须先调用BeginWrite()函数,结束后调用EndWrite()函数。,共享内存的其他技术当使用VCL对象时,使用主VCL线程来执行代码,可确保对象不会间接地访问同时被其他线程中的VCL对象使用的内存。若全局变量不需要被多个线程共享,可使用线程变量来代替它。线程可以不需要等待或暂停其他线程。2,等待其他线程若线程必须等待另一线程完成某项任务,可让线程临时中断执行。然后要么等待另一线程完全执行结束,要么等到另一线程通知完成了该项任务。,等待线程执行结束要等待另一线程执行结束,使用它的WaitFor()函数。WaitFor()函数直到那个线程终止才返回,终止的方式要么完成了Execute()函数,要么由于一个异常。例如,下面的代码在访问列表中的对象前等待,直到另一线程填满该列表。void _fastcall TVisitList:Execute()int fileRes;TFillThread *fl=new TFillThread(false);fillRes=f1-WaitFor();/以下进行后续处理上例中,列表对象只在WaitFor()函数指出该列表被填满时才能被访问。返回值由被等待线程的Execute()函数指定。然而,因为调用 WaitFor()函数的线程需要直到另一线程的执行结果,无法以代码调用Execute()函数,Execute()函数也无法返回任何值。所以 TFillThread线程的Execute()函数应该设置ReturnValue属性。ReturnValue通过被其他线程调用的 WaitFor()函数返回。返回值是一个证书,由应用程序确定其含意。,等待任务完成有时,只需等待线程完成一些操作而不是执行结束。为此,可使用一个事件对象。事件对象(TEvent)应具有全局范围以便他们能够为所有线程可见。当一个 线程完成一个被其他线程依赖的操作时,调用TEvent:SetEvent()函数。它发出一个信号,以便任何其他线程可检查并得知操作完成。要关掉信 号则使用ResetEvent
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GSK2636771-Standard-生命科学试剂-MCE
- 2025航天科工天隼实验室招聘4人模拟试卷附答案详解(黄金题型)
- 2025年河南省上蔡第一高级中学招聘教师30人模拟试卷及答案详解(网校专用)
- 2025年户外机柜温控节能项目合作计划书
- 安全培训效果点评课件
- 企业信誉与发展规划承诺函9篇
- 美食电商美食节促销计划
- 2025年甘肃省兰州眼科医院(兰州市第一人民医院眼科)招聘考前自测高频考点模拟试题参考答案详解
- 小学交通安全培训简报课件
- 2025届春季中核集团人才计划招聘模拟试卷附答案详解(突破训练)
- 2025年全国养老护理员资格考试试题及答案解析
- 国企安全环保培训会课件
- 2025年公安院校联考公安院校联考行测题库(附答案)
- 药物的过量反应课件
- 2025年江苏省南京市中考英语真题卷含答案解析
- 商业综合体安保人员培训效果考试试卷及答案
- 炎症与心脑血管疾病
- 天然林保护知识培训内容课件
- 2025九省联考试题生物及答案
- UV转印技术简介
- 子宫内膜异位症
评论
0/150
提交评论