博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi多线程编程中的技巧(转)
阅读量:6277 次
发布时间:2019-06-22

本文共 3969 字,大约阅读时间需要 13 分钟。

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,
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参数,这才是它的真正有用之处。

转载于:https://www.cnblogs.com/rogee/archive/2010/09/20/1831991.html

你可能感兴趣的文章
music-音符与常用记号
查看>>
sql操作命令
查看>>
zip 数据压缩
查看>>
Python爬虫学习系列教程
查看>>
【数据库优化专题】MySQL视图优化(二)
查看>>
【转载】每个程序员都应该学习使用Python或Ruby
查看>>
PHP高级编程之守护进程,实现优雅重启
查看>>
PHP字符编码转换类3
查看>>
rsync同步服务配置手记
查看>>
Android下创建一个sqlite数据库
查看>>
数组<=>xml 相互转换
查看>>
MFC单文档应用程序显示图像
查看>>
poj 2777(线段树的节点更新策略)
查看>>
Swift-EasingAnimation
查看>>
[翻译] BKZoomView
查看>>
C++类设计的一些心得
查看>>
tableVIew删除时的delete按钮被挡住时重写的方法
查看>>
读cookie中文字符乱码问题
查看>>
招募译者翻译并发数据结构
查看>>
普通表转换为分区表
查看>>