第10章其他编程内容摘要:

统并发度高; 进程将内存作为自己独享的资源,每个进程都有自己的内存空间;而线程共享内存空间,并通过共享内存交换信息,因此有利于提高系统效率。 第 10章 其他编程 TThread类 1. TThread类 TThread类是直接从 Tobject继承下来的,它是抽象类,即不能创 建 TThread类的实例,而只能创建 TThread派生类的实例 — 即创 建线程对象。 ● 创建线程对象的方法是,选择 Delphi 7主菜单下的 FileNewOther… ,在弹出的“ New Items”对话框的“ New” 选项卡中选择 Thread Object图标, 如图所示。 第 10章 其他编程 TThread类 ● 当双击 Thread Object图标后,将出现如图所示的对话框,提示输入 线程对象的名称,线程对象名称是一个标识符,如 TestThread。 ● 输入线程对象名后, Delphi 7会自动创建一个包括该线程对象的单 元,该单元给出了线程的框架,其最初的内容如下所示: 第 10章 其他编程 TThread类 unit Unit1。 interface uses Classes。 type TestThread = class(TThread) private { Private declarations } protected procedure Execute。 override。 end。 implementation { } { TestThread } procedure。 begin { Place thread code here } end。 end. 第 10章 其他编程 TThread类 TThread派生类中唯一必须覆盖的方法是 Excute(),即需要定义线程所执行的功能。 当 Create()需要参数为 False,则当调用 Create()后,线程对象的Execute()方法将会自动被调用,即自动地执行 Execute()的代码。 当 Create()需要参数为 False ,则不自动执行 Execute()的代码,而是要通过 TThread的 Resume()方法来唤醒线程。 第 10章 其他编程 TThread类 2. 与 VCL同步 大多数 VCL都要求在任一时刻只允许一个线程访问它,因此在Delphi中使用多线程,还有一个重要的注意事项,即对 VCL访问只能在主线程中进行,这表明所有与用户交互的代码只能在主线程中。 同时, Delphi为了使线程中的方法也能在主线程中执行,在TThread中设置了一个 Synchronize()方法,该方法声明如下: procedure Synchronize(Method:TThreadMethod)。 Synchronize()方法的参数就是用来传递需要在主线程中执行的线程中的方法。 第 10章 其他编程 线程的终止 当线程对象的 Execute()方法执行完毕后,就认为该线程终止了,此时 Delphi会自动调用一个标准例程 EndThread(),该例程将再调用 API函数 ExitThread(),由 ExitThread()来清除线程所占用的栈。 线程终止时,将触发 OnTerminate事件,可以利用在退出 Execute()之前将 FreeOnTerminate属性置为 True的方法来及时清除线程对象。 procedure。 var i:integer。 Begin FreeOnTerminate := True。 //设置 FreeOnTerminate为 true以便及时清除线程对象 For i:=1 to 10000 do begin If Terminated then break。 Value:=Value+1。 end。 End。 第 10章 其他编程 线程的终止 【 例 】 创建如图所示的窗体,单击“开始”按钮后,将创建一个附 属线程,该线程执行一个计算任务,与此同时主线程并发执行,用户可在文本区域输入任意的字符。 示例中所使用的窗体和组件的属性列于表中,未列的属性均取默认值。 主窗体(设计时) 第 10章 其他编程 线程的终止 窗体与组件的属性设置 第 10章 其他编程 线程的终止 ● 保存主窗体单元为 ,源程序如下: unit Main。 interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,ThrdU。 type TMainForm = class(TForm) Label1: TLabel。 Button1: TButton。 Label2: TLabel。 Edit1: TEdit。 Memo1: TMemo。 procedure Button1Click(Sender: TObject)。 end。 第 10章 其他编程 线程的终止 var MainForm: TMainForm。 implementation {$R *.dfm} procedure (Sender: TObject)。 begin (False)。 { 创建线程 , 使其立即执行 } end。 end. 第 10章 其他编程 线程的终止 ● 创建线程单元 ,选择主菜单的 FileNewUnit,输入线程对象名为 TtestThread,再输入以下源程序: unit ThrdU。 interface uses Classes。 type TTestThread = class(TThread) {线程 TTestThread类定义 } private Answer:integer。 protected procedure GiveAnswer。 procedure Execute。 override。 end。 implementation uses SysUtils,Main。 procedure。 begin :=InttoStr(Answer)。 end。 第 10章 其他编程 线程的终止 { TTestThread } procedure。 {执行一个较长的计算任务 } Var i:integer。 begin FreeOnTerminate:=True。 for i:=1 to 2020000 do begin if Terminated then break。 Inc(Answer,Round(abs(sin(sqrt(i)))))。 Synchronize(GiveAnswer)。 {使 GiveAnswer能在主线程中执行 } end。 end。 end. 第 10章 其他编程 线程的终止 ● 单击 F9运行程序,结果如图所示。 第 10章 其他编程 线程同步 编写多线程应用程序时,需要控制好线程间的同步资源访问,以保证线程的安全运行。 所谓线程同步,简单说就是协调线程间的执行时序。 Win32 API提供了一组同步对象,包括信号量、互斥、临界区和事件等,来解决线程的同步问题。 Delphi分别将事件对象和临界区对象封装为 TEvent和TCriticalSection对象,使得事件和临界区更易使用。 第 10章 其他编程 线程同步 1. 临界区 ◆ 临界区是指一次只能由一个线程执行的一段代码。 在使用 临界区之前 , 要使用 InitializeCriticalSection()过程来初始化它 , 其声明如下: procedure InitializeCriticalSection (var lpCriticalSection:TRTLCriticalSection)。 stdcall。 ● lpCriticalSection是一个 TRTLCriticalSection类型的记录 , 在该参数中传递未初始化的记录 , ● InitializeCriticalSection()过程就会填充这个记录。 ● TRTLCriticalSection是一个与临界区资源相关的类型 ,。 第 10章 其他编程 线程同步 ◆ 创建临界区,使用 EnterCriticalSection()和 LeaveCriticalSection()过程来封装代码块。 这两个过程的声明如下: procedure EnterCriticalSection(var lpCriticalSection: TRTLCriticalSection)。 stdcall。 procedure LeaveCriticalSection(var lpCriticalSection: TRTLCriticalSection)。 stdcall。 ◆ 当不再需要 TRTLCriticalSection记录时,要调用DeleteCriticalSection()过程将其删除。 第 10章 其他编程 线程同步 【 例 】 设有一个全局数组,分别用两个线程对其进行两次初始化,需要对这两个线程同步,否则将出现数据不确定的情形。 用临界区方式进行两线程的同步,将对数组各元素赋值的代码设为临界区。 程序界面如图所示,当单击“初始化”按钮后,将生成两个线程并执行,在列表框中显示数组元素值。 ( 1)创建应用程序界面,新建如图所示的窗体,并放置一个 label、一个 button和一个 listbox组件,各组件及其属性设置列于表中。 第 10章 其他编程 线程同步 窗体与组件的属性设置 第 10章 其他编程 线程同步 ( 2)在 Form1对应的 Unit1单元文件中输入程序代码: unit Unit1。 interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,unit2。 Type TForm1 = class(TForm) Button1: TButton。 ListBox1: TListBox。 Label1: TLabel。 procedure Button1Click(Sender: TObject)。 end。 第 10章 其他编程 线程同步 var Form1: TForm1。 CS:TRTLCriticalSection。 // 声明临界区资源记录变量 implementation {$R *.dfm} procedure (Sender: TObject)。 begin InitializeCriticalSection(CS)。 // 初始化临界区 (False)。 // 创建 TinitThread线程对象并执行 (False)。 end。 end. 第 10章 其他编程 线程同步 ( 3)创建线程对象 TinitThread,选择主菜单的 FileNewOther… ,在 New Items的 New选项卡中双击 “ Thread Object”图标,在弹出的对话框中输入线程名 “ TinitThread”。 ( 4)在系统自动新建的 Unit2单元中输入程序代码: unit Unit2。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。