用Delphi 编程时如何利用线程
解决方案 »
- 比较两个文本大小
- 讨论:我应该留守D7,还是与时俱进,使用DELPHI2009?
- 简单问题,简直是送分,快进来看一看啊,先解决者得分,呵呵..
- 检测edit里有非法字符???急用
- 寻求一(小型)医院管理系统的源代码,价格面谈(1000-8000元之间)!
- 哪位给我解释一下Windows的线程?
- 请问如何使用tstringlist的自定义排序回调函数
- 错误处理中为什么不能显示出:错误编号。
- RZSplitter分割控件使用问题
- 老千,老鱼,来看看,关于SQL语句的参数传递..........................
- 为什么从我的vcl控件生成ActiveX控件时会出错?
- Delphi中实现让TListView接收文件拖放
有多个进程同时工作,而每一个进程又包含有多个线程。但只有一个处理
器的计算机不可能真正地“同时”执行多个线程,而是操作系统把时间分成
若干个时间片,然后把一个个时间片分配给每一个线程。 ---- 一个执行了的程序就是一个进程,一个进程则至少有一个主线程。一位
高级程序员,绝不会让自己的程序里面只有一个主线程存在(除非只有很
少的几十行代码),而是尽量让自己的程序在同一时刻里干更多的事,在
比较大一点的应用中尤其如此,象数据库应用程序,在统计的时候我还想
做其他事呢!因此,如何有效地利用线程则是每一个程序员都应了解的。
本文就此简单地谈一下在Delphi 中如何利用线程。 ---- ( 一) 当使用线程时,我们主要有两个任务: ---- (1)创建一个线程。 ---- (2)创建一个能作为线程入口的函数。 ---- Windows API 调用CreateThread 函数来创建一个线程。函数如下: HANDLE CreateThread(LPSECURITY_
ATTRIBUTES lpThreadAttributes,
//线程安全属性地址
DWORD dwStackSize,
//初始化线程堆栈尺寸
LPTHREAD_START_ROUTINE lpStartAddress,
//线程函数所指向的地址
LPVOID lpParameter,
//给线程函数传递的参数
DWORD dwCreationFlags,
//有关线程的标志
LPDWORD lpThreadId
//系统分配给线程的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 100000 do 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);
if hThread=0 then
messagebox(Handle,'Didn’t Create a Thread',nil,MB_OK);
end;
procedure TForm1.NoUsedThreadClick(Sender: TObject);
begin
MyThreadfunc(nil);
//没有创建线程时,直接调用线程函数
end;
end.
---- 上面这个程序介绍了我们在使用线程及未使用线程二种情况下,运行该
程序的反应。当点UsedThread 按钮时,则建立一个线程,这时我们可以在程序
进行计算的同时,改变窗体的尺寸及移动它。当按下NoUsedThread 按钮时,不
建立线程,我们会发现在程序没有计算完之前根本不能做其它任何事情!