各位大虾哥哥们,谁可以指教我怎样在DELPHI里使用多线程啊!(50分)

  • 主题发起人 主题发起人 云中女孩
  • 开始时间 开始时间
www.delphiok.com
一些技巧集,看看后就知道皮毛了。
 
可是这个网上没有介绍关于多线程的文章呀。
 
用Delphi编程时如何利用线程

--------------------------------------------------------------------------------

Windows95是Microsoft公司的第一个真正的多任务操作系统。在每一时刻可以有多个进程同时工作,而每一个进程又包含有多个线程。但只有一个处理器的计算机不可能真正地“同时”执行多个线程,而是操作系统把时间分成若干个时间片,然后把一个个时间片分配给每一个线程。

一个执行了的程序就是一个进程,一个进程则至少有一个主线程。一位高级程序员,绝不会让自己的程序里面只有一个主线程存在(除非只有很少的几十行代码),而是尽量让自己的程序在同一时刻里干更多的事,在比较大一点的应用中尤其如此,象数据库应用程序,在统计的时候我还想做其他事呢!因此,如何有效地利用线程则是每一个程序员都应了解的。本文就此简单地谈一下在Delphi中如何利用线程。

----(一)当使用线程时,我们主要有两个任务:
----(1)创建一个线程。
----(2)创建一个能作为线程入口的函数。
----WindowsAPI调用CreateThread函数来创建一个线程。函数如下:

HANDLE CreateThread(LPSECURITY_
ATTRIBUTESlpThreadAttributes,
//线程安全属性地址
DWORDdwStackSize,
//初始化线程堆栈尺寸
LPTHREAD_START_ROUTINElpStartAddress,
//线程函数所指向的地址
LPVOIDlpParameter,
//给线程函数传递的参数
DWORDdwCreationFlags,
//有关线程的标志
LPDWORDlpThreadId
//系统分配给线程的ID
);
----第一个参数是安全属性,一般设为nil,使用缺省的安全属性。当我们想此线程有另外的子进程时,可改变它的属性。
----第二个参数是线程堆栈尺寸,一般设为0,表示与此应用的堆栈尺寸相同,即主线程与创建的线程一样长度的堆栈。并且其长度会根据需要自动变长。
----第三个参数,也是最重要的一个,是一个指向函数名的指针,但传递时很简单,只需在线程函数名前加上@就可以了。
----第四个参数是你需要向线程函数传递的参数,一般是一个指向结构的指针。不需传递参数时,则这个参数设为nil。
----第五个参数,传入与线程有关的一些标志,如果是CREATE_SUSPENDED,则创建一个挂起的线程,即这个线程本身已创建,它的堆栈也已创建。但这个线程不会被分配给CPU时间,只有当ResumeThread函数被调用后才能执行;当然,也可以调用SuspendThread函数再次挂起线程。要是标志为0,那么一旦建立线程,线程函数就被立即调用。一般传为0即可。
----最后一个参数是系统分配给这个线程的唯一的ID标志。
----下面这个程序MyThreadPro.pas介绍了线程如何建立及使用:

//Your first test Thread Program.
unit MyThreadPro;
interface
uses
Windows,Messages,SysUtils,Classes,
Graphics,Controls,Forms,Dialogs,
StdCtrls;
type
TForm1=class(TForm)
UsedThread:TButton;
NoUsedThread:TButton;
procedure UsedThreadClick(Sender:TObject);
procedure NoUsedThreadClick(Sender:TObject);
var
Form1:TForm1;
implementation
{$R*.DFM}
//这是线程函数,
它可以放在下面程序的任何地方
function MyThreadFunc(P:pointer):Longint;stdcall;
var
i:integer;
DC:HDC;
S:string;
begin

DC:=GetDC(Form1.Handle);
for i:=0 to 100000do
begin

S:=Inttostr(i);
Textout(DC,10,10,Pchar(S),length(S));
end;

ReleaseDC(Form1.Handle,DC);
end;

procedure TForm1.UsedThreadClick(Sender:TObject);
var
hThread:Thandle;//定义一个句柄
ThreadID:DWord;
begin

//创建线程,同时线程函数被调用
hthread:=CreateThread(nil,0,@MyThreadfunc,nil,0,ThreadID);
ifhThread=0then

messagebox(Handle,'Didn’tCreateaThread',nil,MB_OK);
end;

procedure TForm1.NoUsedThreadClick(Sender:TObject);
begin

MyThreadfunc(nil);
//没有创建线程时,直接调用线程函数
end;

end.


上面这个程序介绍了我们在使用线程及未使用线程二种情况下,运行该程序的反应。当点UsedThread按钮时,则建立一个线程,这时我们可以在程序进行计算的同时,改变窗体的尺寸及移动它。当按下NoUsedThread按钮时,不建立线程,我们会发现在程序没有计算完之前根本不能做其它任何事情!
此程序在基于Windows95的Delphi3中运行通过。

重庆邮电学院计算机系综合微机室 马英杰

 
以上是直接用WINDOWs API的线程使用方法。
VCL中可以继承自TThread类并重载其Execute方法来使用线程。
 
to passion:
麻烦你可以说的仔细一些吗?坦白说, 我初入这一行,近似于什么都不懂!!
 
看看delphi的demo吧
../delphi/demos/threads
 
例程附在下文,如果还是看不懂,我把DEMO程序发给你,你一看就明白了
邮件地址: ztaif@hotmail.com

//ThreadDemo.dpr {* 将以下粘贴为一个文本文件,然后改名为 ThreadDemo.dpr*}
program ThreadDemo;

uses
Forms,
MainForm in 'MainForm.pas' {Form1},
Paintth in 'Paintth.pas';

{$R *.res}

begin

Application.Initialize;
Application.Title := '多线程DEMO';
Application.CreateForm(TForm1, Form1);
Application.Run;
end.



//Paintth.pas {* 将以下粘贴为一个文本文件,然后改名为 Paintth.pas*}

unit Paintth;

interface

uses
Classes;

type
TPainterThread = class(TThread)
Protected
Procedure Execute;
override
end;


implementation
{TpainterThread}

uses
MainForm,Graphics;

Procedure TPainterThread.Execute;
var
x,y:integer;
begin

Randomize;
repeat
x:=Random (600);
y:=Random (300);
with Form1.canvasdo

begin

lock;
try
pixels[x,y]:=clblue;
finally
Unlock;
end;

end;

until Terminated;
end;

end.



//MainForm.dfm {* 将以下粘贴为一个文本文件,然后改名为 MainForm.dfm*}

object Form1: TForm1
Left = 227
Top = 128
Width = 601
Height = 397
Caption = '多线程Demo'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = '宋体'
Font.Style = []
OldCreateOrder = False
OnMouseDown = FormMouseDown
PixelsPerInch = 96
TextHeight = 12
object Button1: TButton
Left = 176
Top = 320
Width = 73
Height = 33
Hint = '鼠标在屏幕上按下将画小圆'
Caption = '启动线程'
ParentShowHint = False
ShowHint = True
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 272
Top = 320
Width = 65
Height = 33
Caption = '暂停线程'
TabOrder = 1
OnClick = Button2Click
end
object Button3: TButton
Left = 352
Top = 320
Width = 73
Height = 33
Caption = '退出程序'
TabOrder = 2
OnClick = Button3Click
end
object Timer1: TTimer
Interval = 500
OnTimer = Timer1Timer
Left = 32
Top = 40
end
object Timer2: TTimer
OnTimer = Timer2Timer
Left = 72
Top = 40
end
end

//MainForm.pas {* 将以下粘贴为一个文本文件,然后改名为 MainForm.pas *}
unit MainForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls,Paintth;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Timer1: TTimer;
Timer2: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
procedure Timer1Timer(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
xx,yy:integer;
PT:TPainterThread;
public
{ Public declarations }
end;


var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
//启动线程
Button1.Enabled:=False;
Button2.Enabled:=true;
PT:=TpainterThread.Create(False);
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
//暂停线程
PT.Free;
Button1.Enabled:=true;
Button2.Enabled:=false;
end;


procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
begin

canvas.Lock;
xx:=x;
yy:=y;
try
canvas.Pen.Color:=clYellow;
canvas.Pen.Color:=clYellow;
canvas.Ellipse(x-30,y-30,x+30,y+30);
finally
canvas.Unlock;
end;

timer1.Enabled:=true;
timer2.Enabled:=true;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin

canvas.Lock;
try
canvas.Pen.Color:=clYellow;
canvas.Pen.Color:=clYellow;
canvas.Ellipse(xx-20,yy-20,xx+20,yy+20);
finally
canvas.Unlock;
end;

timer1.Enabled:=false;
end;


procedure TForm1.Timer2Timer(Sender: TObject);
begin

canvas.Lock;
try
canvas.Pen.Color:=clYellow;
canvas.Pen.Color:=clYellow;
canvas.Ellipse(xx-10,yy-10,xx+10,yy+10);
finally
canvas.Unlock;
end;

timer2.Enabled:=false;
end;


procedure TForm1.Button3Click(Sender: TObject);
begin

close;
end;


end.

 
哈哈,作MM真好!
 
這裡的大蝦哥哥真好.:)
 
多人接受答案了。
 
后退
顶部