• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Delphi多线程编程中的技巧

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

1)创建线程 
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, 11, 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参数,这才是它的真正有用之处。 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi–NativeXML,SuperObject,GDI+下载发布时间:2022-07-18
下一篇:
Delphi与Word(一)合并Word 表格中单元格发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap