




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第10章 其他编程 第第10章章 其他编程其他编程 delphi实用教程实用教程第10章 其他编程 10.1 图形图像处理图形图像处理10.1.1画布的通用属性和方法画布的通用属性和方法 1.tcanvas object(画布对象)(画布对象) 常用方法及功能 :(1)arc方法 语法:语法:arc(x1,y1,x2,y2,x3,y3,x4,y4:integer) arc方法在椭圆上画一段弧,椭圆由(x1,y1)、(x2,y2)两点所 确定的椭圆所决定。弧的起点是椭圆圆周和椭圆中心与(x3,y3) 连线的交点。弧矩形终点是椭圆周和椭圆中心与(x4,y4)连线的 交点,以逆时针方向画弧。 例如,
2、以下的程序将在窗口中将在窗口中绘制一个圆弧: procedure tform1.formpaint(sender:tobject);var r:trect;begin r:=getclientrect; canvas.arc(r.left,r.top,r.right,r.bottom,r.right,r.top,r.left,r.top); end;第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法 (2)chord方法语法:语法: chord(x1,y1,x2,y2,x3,y3,x4,y4:integer) chord方法连接椭圆上的两点,椭圆由(x1,y1)、 (x2
3、,y2)两点所确定的矩形决定,(x3,y3)是始点, (x4,y4)是终点。 例如,在form1窗体上放置一个按钮“连接椭圆上的两点”, 双击该按钮,输入下面的代码: procedure tform1.button1click(sender:tobject); var r:trect; beginr:=getclientrect; get coordinates of the current window. canvas.chord(r.left,r.top,r.right,r.bottom,r.right, r.top,r.left,r.top); end; 第10章 其他编程 10.1.1
4、画布的通用属性和方法画布的通用属性和方法canvas类的chord方法示例 第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法(3)brushcopy方法 语法:语法: brushcopy(const dest: trect;bitmap: tbitmap; const source trect;color:tcolor)brushcopy方法把位图的一部分复制到画布的某个矩形区域,并用画笔的当前颜色替换位图的颜色。dest定义画布的一个矩形区域,该矩形用以填充位图,bitmap定义位图;source定义位图中的矩形区域,该区域上的位图将被复制;color定义画笔中,用以
5、替换位图的颜色。 第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法(4)copyrect方法 语法:语法: copyrect(dest:trect;canvas:tcanvas;sourcetrect)此方法从另一个画布对象上复制部分图像到该画布。canvas表示复制画布,source是源画布上要复制的图像区域,dest表示目标画布上将接受复制图像的矩形区域。 第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法(5)draw方法 语法:语法:draw(x,y:integer;graphic:tgraphic)此方法在画布给定的像素点坐标(x,y)处
6、画由参数graphic所给的图像,该图像可以是位图、图标或元位图。tcanvas的其他方法列于表中。 第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法2. tpen object(画笔对象)画笔对象) 用于在画布上绘制各种线段,该对象常用的属性有:l color:定义笔的颜色;l width:定义线段宽度;l style:定义线段的各种类型,如表所示; 第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法 mode:定义线段的颜色,取值如表所示。 第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法3. tbrush object
7、(画刷对象)(画刷对象)画刷对象用以填充图形,如用画刷颜色或图案对矩形或椭圆进行填充。tbrush拥有一个画刷句柄(hbrush)。画刷的颜色定义在color属性中,画刷还有一个bitmap属性,该属性只能在运行时得到,画刷可使用位图填充图形以产生特殊效果。 第10章 其他编程 10.1.1画布的通用属性和方法画布的通用属性和方法4. tcolor类型类型 tcolor类型用于定义一个对象的颜色。很多部件的颜色属性就是tcolor类型,在graphics单元中tcolor定义如下:tcolor=-(color_endcolors+1)$02fffff;第10章 其他编程 10.1.2 图形图像
8、组件图形图像组件 1.image组件组件 image组件是一个容器组件,它在应用程序窗体窗口中提供了一个矩形区域,用于显示和输出位图、图标、图元文件或用户自定义的图形文件。image组件的常用属性表。 第10章 其他编程 10.1.2 图形图像组件图形图像组件 2. shape组件组件 shape组件用于在窗体中绘制几何图形,如椭圆、矩形和圆角矩形等。该组件的常用属性有: l shape:指明需要绘制的几何图形,它可能的取值和含义 如表所示; l brush:指明在几何图形中填充的样式; l pen:指定几何图形所使用的线型。 第10章 其他编程 10.1.2 图形图像组件图形图像组件 3.
9、paintbox组件组件 该组件是一个简单的画板,它为应用程序提供了可在窗体的特定矩形区域内画图的方法。paintbox组件的主要属性有: (1) anchors属性 该属性包含4个子属性(akleft、aktop、akright和akbotton),用来指定在运行过程中,当父组件是可调时,它相对于父组件边沿的位置。(2) boundsrect属性 该属性用来指定组件的矩形边界,用其父组件的坐标系来表示。 第10章 其他编程 10.1.2 图形图像组件图形图像组件 例如,以下代码用于绘制矩形:procedure tform1.button1click(sender:tobject);var m
10、yrect:trect;begin myrect:=activecontrol.boundsrect; myrect.right=myrect.left+2*(myrect.right-myrect.left); myrect.botton:=myrect.top+(myrect.botton-myrect.top) div 2; activecontrol.boundsrect:=myrect;end;(3) canvas属性 该属性仅在运行时有效,使用该属性可以在组件表面的特定区域进行绘图。 (4) color属性该属性可用于除“颜色”对话框以外的所有组件或对象。 (5) constain
11、ts属性该属性强制指定组件的大小。 第10章 其他编程 10.1.3图形(图形(picture)对象)对象 1.读取图像读取图像 读取图像需要使用loadfromfile方法来调用,同时配合 opendialog函数来选择相应的图像文件。下面的代码实现对 图像文件的读取: procedure tform1.open1click(sender:tobject); begin if opendialog1.execute then begin currentfile:=opendialog1.filename;image.picture.loadfromfile(currentfile); end
12、; end; 第10章 其他编程 10.1.3图形(图形(picture)对象)对象 2. 保存图像保存图像 为将image组件中的图像保存为文件,可调用image组件的picture属性的savetofile方法。savetofile方法需要一个保存文件的文件名。下面的代码是一般程序常用的“save”和“save as”菜单的处理程序: procedure tform1.save1click(sender:tobject) beginif currentfile then image.picture.savetofile(currentfile)else saveasclick(sender
13、);end;procedure tform.saveas1click(sender:tobject);begin if savedialog1.execute then begin currentfile:=savedialog1.filename; save1click(sender); end;end; 第10章 其他编程 10.1.3图形(图形(picture)对象)对象 3. 替换图像替换图像 用户可以在任何进修替换掉image组件中的图像,只要将一新的图像对象赋给picture就可以了。下面的代码实现用一个新的位图对象代替原有的image组件中的picture中的图像对象的功能:bi
14、tmap:tbitmap:beginbitmap:=tbitmap.create;bitmap.width:=newwidth;bitmap.height:=newheight;image.picture.graphic:=bitmap;currentfile:=;end; 第10章 其他编程 10.1.3图形(图形(picture)对象)对象 【例】屏幕复制,将当前屏幕的图像抓下来,显示到窗口中;还可以【例】屏幕复制,将当前屏幕的图像抓下来,显示到窗口中;还可以文件的形式保存起来。步骤如下:文件的形式保存起来。步骤如下: (1) 建立用户界面:建立窗体form1,添加一个panel、一个ti
15、mer、 一个savepicturedialog、四个button控件并在panel控件上添加一个 image控件。 (2) 再创建窗体form2,用于窗口抓图的显示窗口;在该窗体中添加一个image控件和timer控件,其中image控件用于保存图像。 (3) 设置控件属性:对添加的控件按下表设置其属性。第10章 其他编程 10.1.3图形(图形(picture)对象)对象 控件的属性设置 第10章 其他编程 10.1.3图形(图形(picture)对象)对象(4) 激活第一个单元文件,单击delphi 7的file菜单下的use unit项, 出现窗口,选择unit2,单击ok。(5) 编
16、写程序代码如下 : procedure tform1.timer1timer(sender: tobject); / 完成对屏幕的复制,并粘帖到image控件中 var fullscreen:tbitmap; fullscreencanvas:tcanvas; dc:hdc; begin timer1.enabled:=false; fullscreen:=tbitmap.create; / 建立一个bitmap来存放图像 fullscreen.width:=screen.width; dc:=getdc(0); / api函数,获取屏幕 fullscreencanvas:=tcanvas.c
17、reate;/ 建立一个canvas对象 fullscreencanvas.handle:=dc; fullscreen.canvas.copyrect(rect(0,0,screen.width,screen.height), fullscreencanvas,rect(0,0,screen.width,screen.height);第10章 其他编程 10.1.3图形(图形(picture)对象)对象 fullscreencanvas.free; releasedc(0,dc); image1.picture.bitmap:=fullscreen; / 将拷贝下的图像赋给image对象 i
18、mage1.width:=fullscreen.width; image1.height:=fullscreen.height; fullscreen.free; form1.windowstate:=wsnormal; form1.show; messagebeep(1); end; procedure tform1.button4click(sender: tobject); begin close; end;第10章 其他编程 10.1.3图形(图形(picture)对象)对象 procedure tform1.button1click(sender: tobject); begin f
19、orm1.windowstate:=wsminimized; form1.hide; timer1.enabled:=true; end; procedure tform1.button3click(sender: tobject); begin if form1.savepicturedialog1.execute then begin form2.image1.picture.savetofile(savepicturedialog1.filename); end; end;第10章 其他编程 10.1.3图形(图形(picture)对象)对象procedure tform1.button
20、2click(sender: tobject); begin form1.hide; form2.hide; form2.timer1.enabled:=true; end; end. var form2: tform2; foldx,x1,y1,x2,y2,oldx,oldy,foldy:integer;flag,trace:boolean;implementationuses unit3;$r *.dfm第10章 其他编程 10.1.3图形(图形(picture)对象)对象 procedure tform2.timer1timer(sender: tobject); var fullscr
21、een:tbitmap;fullscreencanvas:tcanvas;dc:hdc; beginform2.timer1.enabled:=false; fullscreen:=tbitmap.create; fullscreen.width:=screen.width; fullscreen.height:=screen.height; dc:=getdc(0); fullscreencanvas:=tcanvas.create; fullscreencanvas.handle:=dc; fullscreen.canvas.copyrect(rect(0,0,screen.width,s
22、creen.height), fullscreencanvas,rect(0,0,screen.width,screen.height); fullscreencanvas.free; releasedc(0,dc);第10章 其他编程 10.1.3图形(图形(picture)对象)对象 image1.picture.bitmap:=fullscreen; image1.width:=fullscreen.width; image1.height:=fullscreen.height; fullscreen.free; form2.windowstate:=wsnormal; form2.sh
23、ow; messagebeep(1); foldx:=-1; foldy:=-1; image1.canvas.pen.mode:=pmnot; / 笔的模式取反 image1.canvas.pen.color:=clblack;/ 笔的颜色 image1.canvas.brush.style:=bsclear; / 刷子的格式 flag:=true; end;第10章 其他编程 10.1.3图形(图形(picture)对象)对象 procedure tform2.image1mousemove(sender:tobject;shift:tshiftstate;x,y:integer); be
24、gin if trace=true then / 追踪鼠标 begin / 擦除旧的图形并画上新的图形 with image1.canvas do begin rectangle(x1,y1,oldx,oldy); rectangle(x1,y1,x,y); oldx:=x; oldy:=y; end; end else if flag=true then第10章 其他编程 10.1.3图形(图形(picture)对象)对象begin with image1.canvas do begin moveto(foldx,0); lineto(foldx,screen.height); moveto
25、(0,foldy); lineto(screen.width,foldy); moveto(x,0); lineto(x,screen.height); moveto(0,y); lineto(screen.width,y); foldx:=x; foldy:=y; end; end; end;第10章 其他编程 10.1.3图形(图形(picture)对象)对象 procedure tform2.image1mousedown (sender:tobject;button:tmousebutton;shift:tshiftstate;x,y:integer); / 绘制区域图像 var wi
26、dth,height:integer; newbitmap:tbitmap; begin if(trace=false) then begin / 首次点击鼠标左键,开始追踪鼠标 flag:=false; with image1.canvas do begin moveto(foldx,0); lineto(foldx,screen.height); moveto(0,foldy); lineto(screen.width,foldy);第10章 其他编程 10.1.3图形(图形(picture)对象)对象end; x1:=x; y1:=y; oldx:=x; oldy:=y; trace:=
27、true; image1.canvas.pen.color:=clblack; image1.canvas.brush.style:=bsclear; end else begin / 第2次点击鼠标,得到矩形,并将它拷贝到form1的image上 x2:=x; y2:=y; trace:=false;第10章 其他编程 10.1.3图形(图形(picture)对象)对象image1.canvas.rectangle(x1,y1,oldx,oldy); width:=abs(x2-x1); height:=abs(y2-y1); orm1.image1.width:=width; form1.
28、image1.height:=height; newbitmap:=tbitmap.create; / 生成bitmap对象 newbitmap.width:=width; n e w b i t m a p . h e i g h t : = h e i g h t ; newbitmap.canvas.copyrect(rect(0,0,width,height),form2.image1.canvas,rect(x1,y1,x2,y2); form1.image1.picture.bitmap:=newbitmap;/ 放到form的image上 newbitmap.free; form
29、2.hide; form1.show; end;end;end.第10章 其他编程 10.1.3图形(图形(picture)对象)对象(6) 运行得到如图的结果。 第10章 其他编程 10.2 多媒体编程多媒体编程 10.2.1 简易媒体播放器实例简易媒体播放器实例 制作一个媒体播放器,需要在窗体上设置一个tmediaplayer(该组件位于组件面板的system选项卡上,图标为)、十个tbutton、一个topendialog(位于组件面板的dialogs选项卡上,图标为)等组件)、一个edit、一个combobox、一个timer如图所示。各个组件的名字(name属性)采用默认值。 第10
30、章 其他编程 10.2.1 简易媒体播放器实例简易媒体播放器实例该媒体播放器的工作过程是:单击“打开”按钮,就会打开opendialog对话框,让用户从中选择一个文件。单击 “播放”按钮,就会播放用户所选择的文件。下面的代码是用于处理button8的onclick事件,它将打开媒体播放器。 procedure tform1.button8click(sender:tobjict); begin if opendialog1.execute then begin mediaplayer1.filename:=opendialog1.filename; mediaplayer1.open end;
31、 end. 第10章 其他编程 10.2.1 简易媒体播放器实例简易媒体播放器实例为了opendialog对话框只列出多媒体文件,需要在属性查看器中设置opendialog1的filter属性,单击打开filter属性设置旁的按钮,将打开filter editor对话框,如图所示,在该对话框中键入所要打开文件的类型,如*.wav、*.avi、*.mid等,单击ok。设置好上述内容后,保存该工程,这样一个简单的媒体播放器就制作好了。运行这个程序,打开一个多媒体文件即可。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件 1. mediaplayer组件组件 媒体播放器组件媒体播放器
32、组件 媒体播放器组件属性媒体播放器组件属性 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件2. mediaplayer组件的属性组件的属性(1)autoenable属性 该属性值是boolean类型。如果这个属性设为true,媒体播放器在运行过程中能够自动控制哪些按钮当前可用,哪些按钮当前不可用(不可用的按钮以灰色显示)。 (2)autoopen属性 该属性值是boolean类型。如果这个属性设为true,媒体播放器自动打开devecetype属性指定的多媒体设备(如果devicetype属性设为dtautoselect,媒体播放器将自动打开filename属性中指定的文件)。
33、 (3)autorewind属性 该属性值是boolean类型,用于设置是否具有自动重绕功能。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件(4)capabilities属性 该属性值是只读tmpdevcapsset类型,返回当前设备可以进行 的操作,它的值及值的含义如表所示。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件(5)coloredbutton属性 该属性值是tbuttonset集合类型,用于设置哪些按钮彩色显示,哪些按钮用黑白显示,默认时全部按钮均用彩色显示。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件 mediaplayer
34、组件的其他属性列于表中。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件上表mode属性的取值及含义见表 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件3. mediaplayer组件的过程和函数组件的过程和函数 (1)autobuttonset过程 该过程用来指定媒体播放器的按钮是否可用。 (2)back过程 该过程使媒体播放器退回数个帧。 (3)click过程 这是一个动态过程,该过程决定当onclick事件被触发时执行什么动作。在默认状态下,当onclick事件触发时,该过程不招待任何动作,仅仅是调用一个事件处理程序,连接到媒体播放器的onclick事件处
35、理程序中。该过程可以根据需要重新加载事件处理程序。 (4)close过程该过程关闭已打开的多媒体播放设备。当应用程序中止时,自动调用该过程。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件(5)create函数 这是一个动态的构造函数,该函数可在运行时建立一个 mediaplayer对象,并对其进行初始化,使得媒体播放器既可 以在设计时静态建立,也可以在运行时通过调用create方法 动态建立。(6)destroy函数 这是一个动态的析构函数,该函数用于撤销媒体播放器对象。 应用程序不能直接调用该函数,应先调用free过程检查媒体播 放器对象是否空闲,如果空闲就释放其占用的内存
36、空间。该函 数执行前,必须确保媒体设备已经关闭。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件mediaplayer媒体播放器的其他过程表。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件 mediaplayer媒体播放器的其他过程表。第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件4. mediaplayer组件的事件组件的事件 (1)onclick事件 当用户移动光标到媒体播放器控制按钮组的任一按钮上,单击鼠标左键或者当媒体播放器控制按钮获得焦点时,单击空格键都将会触发该事件。(2)onnotify事件 如果notify属性设置为true,当
37、一个媒体控制方法( 如back、close、eject、next、open、pause、pauseonly、 play.previous、resume、startrecording、step、stop等)执 行结束时,触发该事件。onnotify事件触发后,必须重新 设置notify属性为true,以便触发下一个onnotify事件。 第10章 其他编程 10.2.2 媒体播放器组件媒体播放器组件(3)onpostclick事件 当onclick事件处理程序被调用以后,触发该事件。(4)onenter事件 当一个控件接收到键入焦点时,触发该事件。 第10章 其他编程 10.3 线程线程 10.
38、3.1 线程概念线程概念 所谓多线程,是指操作系统同时运行多个执行体的能力。线程概念与并发性是紧密相关的,多线程的出发点就是为了提高系统的并发度。 线程与进程的差别主要体现在两个方面: 线程和进程虽然都是系统的基本执行单元,线程的划分单位比进程小,因此支持多线程的系统比只支持多进程的系统并发度高;进程将内存作为自己独享的资源,每个进程都有自己的内存空间;而线程共享内存空间,并通过共享内存交换信息,因此有利于提高系统效率。 第10章 其他编程 10.3.2 tthread类类 1.tthread类类 tthread类是直接从tobject继承下来的,它是抽象类,即不能创建tthread类的实例,
39、而只能创建tthread派生类的实例即创建线程对象。 创建线程对象的方法是,选择delphi 7主菜单下的filenewother,在弹出的“new items”对话框的“new”选项卡中选择thread object图标,如图所示。 第10章 其他编程 10.3.2 tthread类类 当双击thread object图标后,将出现如图所示的对话框,提示输入 线程对象的名称,线程对象名称是一个标识符,如testthread。 输入线程对象名后,delphi 7会自动创建一个包括该线程对象的单 元,该单元给出了线程的框架,其最初的内容如下所示: 第10章 其他编程 10.3.2 tthread
40、类类unit unit1;interfaceuses classes; type testthread = class(tthread) private private declarations protected procedure execute; override;end;implementation testthread procedure testthread.execute;begin place thread code here end;end.第10章 其他编程 10.3.2 tthread类类tthread派生类中唯一必须覆盖的方法是excute(),即需要定义线程所执行的功
41、能。 当create()需要参数为false,则当调用create()后,线程对象的execute()方法将会自动被调用,即自动地执行execute()的代码。当create()需要参数为false ,则不自动执行execute()的代码,而是要通过tthread的resume()方法来唤醒线程。 第10章 其他编程 10.3.2 tthread类类2. 与与vcl同步同步 大多数vcl都要求在任一时刻只允许一个线程访问它,因此在delphi中使用多线程,还有一个重要的注意事项,即对vcl访问只能在主线程中进行,这表明所有与用户交互的代码只能在主线程中。同时,delphi为了使线程中的方法也能
42、在主线程中执行,在tthread中设置了一个synchronize()方法,该方法声明如下:procedure synchronize(method:tthreadmethod); synchronize()方法的参数就是用来传递需要在主线程中执行的线程中的方法。 第10章 其他编程 10.3.3 线程的终止线程的终止 当线程对象的execute()方法执行完毕后,就认为该线程终止了,此时delphi会自动调用一个标准例程endthread(),该例程将再调用api函数exitthread(),由exitthread()来清除线程所占用的栈。线程终止时,将触发onterminate事件,可以利
43、用在退出execute()之前将freeonterminate属性置为true的方法来及时清除线程对象。procedure testthread.execute;var i:integer;begin freeonterminate := true; /设置freeonterminate为true以便及时清除线程对象 for i:=1 to 10000 dobegin if terminated then break; value:=value+1; end;end; 第10章 其他编程 10.3.3 线程的终止线程的终止 【例】【例】创建如图所示的窗体,单击“开始”按钮后,将创建一个附 属线
44、程,该线程执行一个计算任务,与此同时主线程并发执行,用户可在文本区域输入任意的字符。示例中所使用的窗体和组件的属性列于表中,未列的属性均取默认值。 主窗体(设计时)主窗体(设计时) 第10章 其他编程 10.3.3 线程的终止线程的终止 窗体与组件的属性设置 第10章 其他编程 10.3.3 线程的终止线程的终止保存主窗体单元为main.pas,源程序如下: unit main; interface uses windows, messages, sysutils, variants, classes, graphics, controls, forms, dialogs, stdctrls,
45、thrdu; type tmainform = class(tform) label1: tlabel; button1: tbutton; label2: tlabel; edit1: tedit; memo1: tmemo; procedure button1click(sender: tobject); end; 第10章 其他编程 10.3.3 线程的终止线程的终止var mainform: tmainform;implementation$r *.dfmprocedure tmainform.button1click(sender: tobject);begin ttestthrea
46、d.create(false); 创建线程,使其立即执行 end;end.第10章 其他编程 10.3.3 线程的终止线程的终止创建线程单元thrdu.pas,选择主菜单的filenewunit,输入线程对象名为ttestthread,再输入以下源程序:unit thrdu;interfaceuses classes;type ttestthread = class(tthread) 线程ttestthread类定义 private answer:integer; protected procedure giveanswer; procedure execute; override;end;i
47、mplementationuses sysutils,main;procedure ttestthread.giveanswer;begin mainform.edit1.text:=inttostr(answer);end;第10章 其他编程 10.3.3 线程的终止线程的终止 ttestthread procedure ttestthread.execute; 执行一个较长的计算任务var i:integer;begin freeonterminate:=true; for i:=1 to 2000000 do begin if terminated then break; inc(ans
48、wer,round(abs(sin(sqrt(i); synchronize(giveanswer); 使giveanswer能在主线程中执行 end;end;end.第10章 其他编程 10.3.3 线程的终止线程的终止单击f9运行程序,结果如图所示。 第10章 其他编程 10.3.4 线程同步线程同步 编写多线程应用程序时,需要控制好线程间的同步资源访问,以保证线程的安全运行。 所谓线程同步,简单说就是协调线程间的执行时序。win32 api提供了一组同步对象,包括信号量、互斥、临界区和事件等,来解决线程的同步问题。 delphi分别将事件对象和临界区对象封装为tevent和tcritic
49、alsection对象,使得事件和临界区更易使用。 第10章 其他编程 10.3.4 线程同步线程同步1.临界区临界区 临界区是指一次只能由一个线程执行的一段代码。在使用 临界区之前,要使用initializecriticalsection()过程来初始化它, 其声明如下:procedure initializecriticalsection(var lpcriticalsection:trtlcriticalsection);stdcall; lpcriticalsection是一个trtlcriticalsection类型的记录, 在该参数中传递未初始化的记录, initializecri
50、ticalsection()过程就会填充这个记录。 trtlcriticalsection是一个与临界区资源相关的类型,。 第10章 其他编程 10.3.4 线程同步线程同步创建临界区,使用entercriticalsection()和leavecriticalsection()过程来封装代码块。这两个过程的声明如下:procedure entercriticalsection(var lpcriticalsection: trtlcriticalsection);stdcall;procedure leavecriticalsection(var lpcriticalsection: trt
51、lcriticalsection);stdcall; 当不再需要trtlcriticalsection记录时,要调用deletecriticalsection()过程将其删除。 第10章 其他编程 10.3.4 线程同步线程同步【例】【例】设有一个全局数组,分别用两个线程对其进行两次初始化,需要对这两个线程同步,否则将出现数据不确定的情形。用临界区方式进行两线程的同步,将对数组各元素赋值的代码设为临界区。程序界面如图所示,当单击“初始化”按钮后,将生成两个线程并执行,在列表框中显示数组元素值。 (1)创建应用程序界面,新建如图所示的窗体,并放置一个 label、一个button和一个listb
52、ox组件,各组件及其属性设置列于表中。 第10章 其他编程 10.3.4 线程同步线程同步窗体与组件的属性设置 第10章 其他编程 10.3.4 线程同步线程同步 (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: tlistb
53、ox; label1: tlabel; procedure button1click(sender: tobject); end; 第10章 其他编程 10.3.4 线程同步线程同步var form1: tform1; cs:trtlcriticalsection; / 声明临界区资源记录变量implementation$r *.dfmprocedure tform1.button1click(sender: tobject);begin initializecriticalsection(cs); / 初始化临界区 tinitthread.create(false); / 创建tinitth
54、read线程对象并执行 tinitthread.create(false);end;end.第10章 其他编程 10.3.4 线程同步线程同步(3)创建线程对象tinitthread,选择主菜单的 filenewother,在new items的new选项卡中双击 “thread object”图标,在弹出的对话框中输入线程名 “tinitthread”。(4)在系统自动新建的unit2单元中输入程序代码: unit unit2; interface uses windows, sysutils, classes; / 在此要添加windows和sysutils type以下是tinitthr
55、ead类定义 tinitthread = class(tthread) protected procedure showresult; / 显示结果 procedure execute; override; end; 第10章 其他编程 10.3.4 线程同步线程同步implementationuses unit1; const size=10; / 数组大小var next:integer=0; / 全局变量定义 tag:integer=0; a:array 1.size of integer; procedure tinitthread.showresult; var i:integer;
56、 begin inc(tag); if tag=2 then begin / 两个线程均执行完毕 for i:=1 to size do /在列表框中显示数组各元素值 form1.listbox1.items.add(inttostr(ai); deletecriticalsection(cs); / 移去临界区 end;end;第10章 其他编程 10.3.4 线程同步线程同步procedure tinitthread.execute; var i:integer; begin entercriticalsection(cs); / 进入临界区 for i:=1 to size do / 为
57、数组各元素赋值begin ai:=next; inc(next); sleep(5); end; leavecriticalsection(cs); / 临界区终止 synchronize(showresult);/ 使showresult能在主线程中执行end; end.第10章 其他编程 10.3.4 线程同步线程同步(5)单击f9运行程序,结果如图所示。 第10章 其他编程 10.3.4 线程同步线程同步说明:说明:在第一个线程调用了entercriticalsection()之后,其他的线程就不能进入临界区代码,它们将睡眠;直到第一个线程调用leavecriticalsection()
58、后,下一个需要进入临界区的线程才被唤醒。 第10章 其他编程 10.3.4 线程同步线程同步2. 互斥互斥 (1)互斥(mutex)与临界区非常相似,但有两个主要区别:互斥可用于不同进程的线程间同步,而临界区不可;互斥可被赋予一个字符串名,通过该名字可创建该互斥对象的 附加句柄。(2)创建互斥对象的函数是createmutex(),其原型为 function createmutex(lpmutexattibutes:psecurityattributes;binitialowner:bool;lpname:pchar):thandle;stdcall; lpmutexattibutes参数为一
59、个指向tsecurityattributes记录的指针,通 常置为0,表示使用默认的安全属性。 binitialowner参数用于指出创建互斥对象的线程是否要成为此互斥对 象的拥有者,该参数为false表示互斥对象没有拥有者。 lpname参数指出互斥对象的名称 。第10章 其他编程 10.3.4 线程同步线程同步(3)互斥对象不再使用时,应调用closehandle()过程来关闭它。当 一个线程不需再拥有互斥对象时,应调用releasemutex()过程。 (4)为了防止其他线程进入同步区代码,需使用aitforsingleobject() 函数,原型为:function waitforsi
60、ngleobject(hhandle: thandle; dwmilliseconds:dword):dwaord;stdcall; dwmilliseconds参数可设为两个值: 当值为0时,函数将只检查由hhandle参数指定的互斥对象是否处 于发信号状态,检查完毕后函数立即返回 当值为infinite时,则函数将一直等待,直到信号出现为止 hhandle参数指定的互斥对象 返回值有3种: wait_abandoned,表明指定对象是互斥对象,并且拥有该 互斥对象的线程在未释放该对象之前就已终止 wait_object_0,表明指定的对象处于发信号状态 wait_timeout,表明等待的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 乐视无人机发布会捷豹合作方案
- CN120209323A 基于双重接枝的多功能化助剂、制备方法及在片材中应用
- 老年人安全生产知识培训课件
- 外研社版英语八年级下册 Module 7单元测试及答案02
- 数的运算(考点突破)-六年级下册小升初数学思维拓展提升讲义
- 配饰电镀科普知识培训课件
- 人教版八年级英语下册重点语法过关:过去进行时(含答案)
- 人教版八年级英语下册期末检测卷(一)含答案解析
- CN120197286A 混合模块建筑的建模分析方法、装置、设备及介质
- 老人营养学知识培训总结课件
- 2022年北京语言大学各单位新编长聘人员招聘需求笔试备考题库及答案解析
- 2022年四川雅安石棉县综合类事业单位招聘20人笔试备考题库及答案解析
- 部编版小学语文四年级上册课程纲要
- 完整解读中华人民共和国政府信息公开条例课件
- 幼儿园红色故事绘本:《闪闪的红星》 课件
- GB/T 5780-2016六角头螺栓C级
- 小学特色作业经验汇报课件
- 粘膜免疫 2课件
- 统计业务知识(统计法规)课件
- 地质勘察任务书模板
- 新湘科版科学五年级上册全册课件(精品PPT)
评论
0/150
提交评论