Delphi多线程编程中的技巧
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)使用信号量
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/1832057.html
Delphi多线程编程中的技巧相关推荐
- 详解Java多线程编程中LockSupport类的线程阻塞用法
转载自 详解Java多线程编程中LockSupport类的线程阻塞用法 LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport实际 ...
- Java多线程编程中Future模式的详解
转载自 https://www.cnblogs.com/winkey4986/p/6203225.html Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker ...
- 对linux中多线程编程中pthread_join的理解
对linux中多线程编程中pthread_join的理解 分类: 程序员面试 linux学习2013-08-04 21:32 234人阅读 评论(0) 收藏 举报 多线程linuxpthread_jo ...
- Java多线程编程(2)--多线程编程中的挑战
一.串行.并发和并行 为了更清楚地解释这三个概念,我们来举一个例子.假设我们有A.B.C三项工作要做,那么我们有以下三种方式来完成这些工作: 第一种方式,先开始做工作A,完成之后再开始做工作B ...
- Delphi 多线程编程(1)
本文的内容取自万一博客,并重新加以整理,在此留存仅仅是方便自己学习和查阅.所有代码均亲自测试 delphi7下测试有效.图片均为自己制作. 多线程应该是编程工作者的基础技能, 但这个基础我从来没学过, ...
- Delphi多线程编程基础入门
1. 概述 对于开发人员来说,多线程是必备的知识,但相对来说,也是比较难的知识点.Delphi是一门古老而优秀的编程语言,它对多线程的处理有一些特殊的地方,本文尝试做一些简单的讲解,可以当作Delph ...
- java 多线程同步_详解Java多线程编程中的线程同步方法
1.多线程的同步: 1.1.同步机制:在多线程中,可能有多个线程试图访问一个有限的资源,必须预防这种情况的发生.所以引入了同步机制:在线程使用一个资源时为其加锁,这样其他的线程便不能访问那个资源了,直 ...
- C语言中pthread或Windows API在多线程编程中的基本应用
文章目录 多线程概述 掌握多线程需要学习什么? 使用pthread.h实现多线程 使用Windows API实现多线程 使用threads.h实现多线程 参考资料 警告 由于我懒得写完,而且懂的也不是 ...
- Linux下多线程编程中信号量介绍及简单使用
在Linux中有两种方法用于处理线程同步:信号量和互斥量. 线程的信号量是一种特殊的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作.如果一个程序中有多个线程试图改变一个信号量的值,系统将保 ...
最新文章
- uni-app 之 使用扩展组件(uni ui) Pagination 分页器使用示例
- 课时 18-Kubernetes 调度和资源管理(子誉)
- 支付宝招兼职“找茬程序员” 不用坐班/最高奖励36万
- 性能测试报告模板_性能测试规范之测试报告
- java treeset比较,java中TreeSet的两种排序比较的方式
- ZBlog通用视频插件 - ZblogPHP视频播放插件
- 浅析android应用增量升级
- 适合 Java 新手的开源项目集合——在 GitHub 学编程
- 1024 科学计数法(C语言详解)
- jrtplib 打包做了哪些事_使用jrtplib打包发送h264数据,关使用vlc|mplayer播放 | 学步园...
- BIG5码转换为GB2312码的方法
- xdoj系统_基于RBRVS和DRGs的医院绩效管理体系如何建立?
- 控制算法和编程算法_算法中的编程公平性
- 小程序打开速度慢是服务器原因吗,网页打开速度慢的原因以及解决方法
- VMware View Client 连接服务器,提示身份验证失败,连接服务器时
- 盘点那些你不知道的开源软件
- 计算机与通信英语,数据与计算机通信(第十版)(英文版)
- 关于我自学爬虫的经历,当你真心想做一件事情的时候,全世界都会帮你
- 搭建新浪SAE服务器
- 【失败】尝试改hosts突破迅雷离线的封锁
热门文章
- hessiancpp编译和使用(C++版)
- 码农技术炒股之路——实时交易信息、主力动向信息分库备份
- Windows客户端C/C++编程规范“建议”——结构
- OpenBLAS简介及在Windows7 VS2013上源码的编译过程
- matlab外部接口简介
- 票据自动处理系统著名研究团队
- oracle数据库配置失败,oracle11g – Oracle 11G XE安装错误:数据库配置失败
- python开源商城_Leaf - 一个开发友好、功能完备的开源微信商城框架
- Java学习总结:36(日期处理类)
- 模糊匹配 读音_onenote搜索机制详解②:两种搜索模式,模糊与精确匹配