Delphi中多线程的技巧

创建线程

MsgThread := TMsgThread.Create(False) ; //创建并执行线程

MsgThread := TMsgThread.Create(True) ; //创建线程后挂起

constructor Create(CreateSuspended: Boolean); 中的参数CreateSuspended表示创建后是否挂起线程。

2)设置线程里没有设置循环执行的话,且设置FreeOnTerminate为True,则线程执行完后就会自己释放。

3)在一个线程结束后,调用另一个事件的方法:

只要设置Onterminate:=某方法,这样在线程结束前自然会被调用,比如 :

procedure TSendShortMessageThread.Execute;

var

Bitmap: Tbitamp;

begin

Bimap:=Tbitmap.create(nil) ;

OnTerminate:=Threaddone;

end;

procedure Threaddone(sender: tobject);

begin

Bimap.Free; //在Destory之前会被调用

end;

4)程序结束前安全的退出线程的方法:

if MsgThread <> nil then

begin

MsgThread.Terminate ;

MsgThread.WaitFor ;

end;

5)判断当前线程的状态:

//以下资料来自大富翁论坛。

/判断线程是否释放

//返回值:0-已释放;1-正在运行;2-已终止但未释放;

//3-未建立或不存在

function TFrmMain.CheckThreadFreed(aThread: TThread): Byte;

var

i: DWord;

IsQuit: Boolean;

begin

if Assigned(aThread) then

begin

IsQuit := GetExitCodeThread(aThread.Handle, i);

if IsQuit then //If the function succeeds, the return value is nonzero.

//If the function fails, the return value is zero.

begin

if i = STILL_ACTIVE then //If the specified thread has not terminated,

//the termination status returned is STILL_ACTIVE.

Result := 1

else

Result := 2; //aThread未Free,因为Tthread.Destroy中有执行语句

end

else

Result := 0; //可以用GetLastError取得错误代码

end

else

Result := 3;

end;

6)线程同步。

如果线程要调用VCL里面的内容(如:别的窗体中的控件),就需要将这个线程同步。线程同步表示交由主线程运行这段代码,各个线程都在主线程中分时间段运行。另外,要想避免多个线程同时执行同一段代码也需要将多线程同步。

临界区和互斥的作用类似,都是用来进行同步的,但它们间有以下一点差别:

临界区只能在进程内使用,也就是说只能是进程内的线程间的同步;而互斥则还可用在进程之间的;临界区所花消的时间很少,才10~15个时间片,而互斥需要400多个;临界区随着进程的终止而终止,而互斥,如果你不用closehandle()的话,在进程终止后仍然在系统内存在,也就是说它是系统全局对象;

同步的方法有:

(1)使用临界区对象。

临界区对象有两种:TRTLCriticalSection 和 CriticalSection。

?? TRTLCriticalSection的用法

var

GlobalVariable:Double;

var

CriticalSection:TRTLCriticalSection;

procedure SetGlobalVariable(Value:Double);

begin

EnterCriticalSection(CriticalSection); //进入临界区

try

GlobalVariable:=Value;

finally

LeaveCriticalSection(CriticalSection); //离开临界区

end;

end;

initialization

InitializeCriticalSection(CriticalSection); //初始化

finalization

DeleteCriticalSection(CriticalSection); //删除

end.

?? CriticalSection(重要区段)的用法:

var criticalsection: TCriticalsection;

创建:criticalsection := TCriticalsection.create;

使用:

criticalsection.enter;

try

...

finally

criticalsection.leave;

end;

(2)使用互斥

先在主线程中创建事件对象:

var

hMutex: THandle = 0;

...

hMutex := CreateMutex(nil, False, nil);

在线程的Execute方法中加入以下代码:

if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then

//Do Something;

...

ReleaseMutex(hMutex);

最后记得要释放互斥对象:

CloseHandle(hMutex);

(3)使用信号量

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, ExtCtrls, StdCtrls;

type

TForm1 = class(TForm)

Edit1: TEdit;

Button1: TButton;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

type

TMyThread = class(TThread)

private

protected

procedure Execute; override;

public

constructor Create; virtual;

end;

var

Form1 : TForm1;

HSem : THandle = 0 ;

implementation

{$R *.dfm}

var

tick: Integer = 0;

procedure TMyThread.Execute;

var

WaitReturn : DWord ;

begin

WaitReturn := WaitForSingleObject(HSem,INFINITE) ;

Form1.Edit1.Text := IntToStr(tick);

Inc(tick);

Sleep(10);

ReleaseSemaphore(HSem, 1, Nil)

end;

constructor TMyThread.Create;

begin

inherited Create(False);

FreeOnTerminate := True;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

HSem := CreateSemaphore(Nil,1,1,Nil) ;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

CloseHandle(HSem) ;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

index: Integer;

begin

for index := 0 to 10 do

begin

TMyThread.Create;

end;

end;

end.

一般的同步对象使用Mutex对象,是因为Mutex有一个特别之处:当一个持有对象的线程DOWN掉的时候,mutex对象可以自动让其它等待这个对象的线程接受,而其它的内核对象则不具体这个功能。

之所要使用Semaphore则是因为Semaphore可以提供一个活动线程的上限,即lMaximumCount参数,这才是它的真正有用之处。

时间: 2024-07-29 18:30:37

Delphi中多线程的技巧的相关文章

Delphi中多线程用消息实现VCL数据同步显示

Delphi中多线程用消息实现VCL数据同步显示 Lanno Ckeeke 2006-5-12 概述: delphi中严格区分主线程和子主线程,主线程负责GUI的更新,子线程负责数据运算,当数据运行完毕后,子线程可以向主线程式发送消息,以便通知其将VCL中的数据更新. 实现: 关键在于消息的发送及接收.在消息结构Tmessage中wParam和lParam类型为Longint,而指针类型也定义为Longint,可以通过此指针来传递自己所感兴趣的数据.如传递字符数组: 数组定义: const MA

关于Delphi中多线程传递参数的简单问题

http://bbs.csdn.net/topics/390513469/ unit uThread; interface uses Classes; type Th = class(TThread) private { Private declarations } protected procedure Execute; override; end; 以上是创建的一个多线程 我在另外一个单元里Unit1有一个函数 function Myfun(username,password:string)

Delphi中多线程下使用使用 UniDAC+MSSQL 需要注意的问题(连接前调用CoInitialize)

一般解决方法是在线程开始启用 CoInitialize(nil),线程结束调用 CoUninitialize .如果你使用多种数据库连接,比如三层中经常切换到MSSQL和Oracle,我们只需在判断 TUniConnection 的连接前事件 OnBeforeConnect 写下如下代码: [delphi] view plain copy print? procedure TServDBFunc.ServConnBeforeConnect(Sender: TObject); begin if (

delphi中多线程排序

unit ThSort; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TThreadSortForm = class(TForm) StartBtn: TButton; BubbleSortBox: TPaintBox; SelectionSortBox: TPaintBox; QuickSortBox: TPai

Delphi中SendMessage使用说明 good

Delphi中SendMessage使用说明 SendMessage基础知识 函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回. 函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam): 参数: hWnd:其窗口程序将接收消息的窗口的句柄.如果此参数为HWND_BRO

delphi中SendMessage使用说明

SendMessage基础知识 函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回. 函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam): 参数: hWnd:其窗口程序将接收消息的窗口的句柄.如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗

DELPHI中的多线程【深入VCL源码】

线程的基础知识 线程的组成.线程有两部分组成. 1.一个是线程的内核对象,操作系统用它来对线程实施管理.内核对象也是系统用来存放线程统计信息的地方. 2.另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量. 进程从来不执行任何东西,它只是线程的容器.线程总是在某个进程环境中创建的,而且它的整个寿命期都在该进程中.这意味着线程在它的进程地址空间中执行代码,并且在进程的地址空间中对数据进行操作.因此,如果在单进程环境中,你有两个或多个线程正在运行,那么这两个线程将共享单个地址空

Delphi中线程类TThread实现多线程编程(线程同步技术、Synchronize、WaitFor……)

接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event)与Delphi中的事件有所不同.从本质上讲,Event其实就相当于一个全局的布尔变量.它有两个赋值操作:Set和ReSet,相当于把它设置为 True或False.而检查它的值是通过WaitFor操作进行.对应在Windows平台上,是三个API函数:SetEvent.ResetEvent.WaitForSignalObje

Delphi中线程类TThread 实现多线程编程

作者:Rogee出处:Http://Rogee.cnblogs.com/心得:BLOG是什么,它是一个记录学习过程的东西 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchronize的用法就完了.然而这并不是多线程编程的全部,我写此文的目的在于对此作一个补充. 线程本质上是进程中一段并发运行的代码.一个进程至少有一个线程,即所谓的主线程.同时还可以