delphi中临界操作方法

Delphi的多线程开发实例 在软件开发的过程中,多线程的开发应用有着极为重要的位置,使用多线程可以让软件系统能够并行操作、同时也能提高其运行效率。作为软件开发人员的必修课之一,多线程的熟练运用可以让软件系统有更佳的性能表现。以下使用Window Api、Delphi 封装的TThread类来分别创建线程,再以普通方法来执行一个耗时的过程,对比使用线程的好处。1. Windows API 函数直接创建   阅读详情

 

var
    FLock:TRTLCriticalSection; //定义临界区域
begin
   InitializeCriticalSection(FLock); //初始化临界区域
   EnterCriticalSection(FLock); //进入临界区域
   LeaveCriticalSection(FLock); //退出临界区域
   DeleteCriticalSection(FLock);//删除临界区域
end;
//CLASS中使用实例
 TRegGroups = class
 private
    .............
    FLock: TRTLCriticalSection;
    ................
 public
    ...........
    constructor Create;
    destructor Destroy; override;
    procedure Lock;
    procedure Unlock;
    ................
 end;
 
var
 RegGroups: TRegGroups;
 
constructor TRegGroups.Create;
begin
 inherited Create;
 ................
 InitializeCriticalSection(FLock);
 .....................
end;
 
destructor TRegGroups.Destroy;
begin
 DeleteCriticalSection(FLock);
 .......................
 inherited;
end;
 
procedure TRegGroups.Lock;
begin
 EnterCriticalSection(FLock);
end;
 
procedure TRegGroups.Unlock;
begin
 LeaveCriticalSection(FLock);
end;

 

delphi中多线程的简单应用 线程是进程内一个相对独立的、可调度的执行单元。一个应用可以有一个主线程,一个主线程可以有多个子线程,子线程还可以有自己的子线程,这样就构成了多线程应用了。由于多个线程往往会同时访问同一块内存区域,频繁的访问这块区域,将会增加产生线程冲突的概率。一旦产生了冲突,将会造成不可预料的结果(该公用区域的值是不可预料的)可见处理线程同步的必要性。   注意:本文中出现的所有代码都是用DELPHI描述的,调试 阅读详情

相关推荐

Java JNI 和 Delphi 相互調用(2)-Delphi調用Java

繼續前一篇。前幾天寫了  Java JNI 和 Delphi 相互調用(1)-JAVA調用DELPHI ,有朋友要求儘快寫“Delphi調用Java”,現在有空,就寫下去。DELPHI 調用 JAVA 的方法,作為入門也不算複雜,只是創建JVM的環境麻煩一些。進行的順序是:a.建立 JVM 環境b.創建 JAVA 環境實例c.找到 classd.找到方法e.調用方法f.結束如何得到 DELPHI

小橙的第一播 4969

Delphi线程同步(临界区、互斥、信号量)

  当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源。   例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件的字符数。当然,在整个文件调入内存之前,统计它的计数是没有意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当做是互不相干的任务分别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作   存...

weixin_30387339的博客 524

Delphi多线程编程之三 同步读写全局数据

一、临界区 所谓临界区,就是一次只能由一个线程来执行的一段代码。如果把初始化数组的代码放在临界区内,另一个线程在第一个线程处理完之前是不会被执行的。 使用临界区的步骤: 1、先声明一个全局变量类型为TRTLCriticalSection; 2、在线程Create()前调用InitializeCriticalSection()过程来初始化,该函数定义是: void WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 类型lpCriticalSection即是Delphi封装的TRTLCriticalSection。 3、在线程的需要放入临界区的代码前面使用EnterCriticalSection(lpCriticalSection)过程来开始建立临界区。在代码完成后用LeaveCriticalSection(lpCriticalSection)来标志临界区的结束。 4、在线程执行完后用DeleteCriticalSection(lpCriticalSection)来清除临界区。这个清除过程必须放在线程执行完后的地方,比如FormDesroy事件中。上面的例子中,若把该过程放在TMyThread.Create(False);后,会产生错误。 二、互斥: 互斥非常类似于临界区,除了两个关键的区别:首先,互斥可用于跨进程的线程同步。其次,互斥能被赋予一个字符串名字,并且通过引用此名字创建现有互斥对象的附加句柄。 提示临界区与事件对象(比如互斥对象)的最大的区别是在性能上。临界区在没有线程冲突时,要用10~15个时间片,而事件对象由于涉及到系统内核要用400~600个时间片。 使用互斥的步骤: 1、声明一个类型为Thandle或Hwnd的全局变量,其实都是Cardinal类型。Hwnd是handle of window,主要用于窗口句柄;而Thandle则没有限制。 2、线程Create()前用CreateMutex()来创建一个互斥量。该函数定义为: HANDLE WINAPI CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName:Pchar); LPSECURITY_ATTRIBUTES参数为一个指向TSecurityAttributtes记录的指针。此参数设为nil,表示访问控制列表默认的安全属性。 bInitalOwner参数表示创建互斥对象的线程是否要成为此互斥对象的拥有者。当此参数为False时,表示互斥对象没有拥有者。 lpName参数指定互斥对象的名称。设为nil表示无命名,如果参数不是设为nil,函数会搜索是否有同名的互斥对象存在。如果有,函数就会返回同名互斥对象的句柄。否则,就新创建一个互斥对象并返回其句柄。 返回值是一handle。当错误发生时,返回null,此时用GetLastError函数可查看错误的信息。 利用CreateMutex()可以防止程序多个实例运行,如下例: Program ABC; Uses Forms,Windows,…; {$R *.res} Var hMutex:Hwnd; Begin Application.Initialize; hMutex:=CreateMutex(nil,False,Pchar(Application.Title)); if GetLastErrorERROR_ALREADY_EXISTS then begin //项目要运行的咚咚 end; ReleaseMutex(hMutex); Application.Run; End; 在本节的例程中,我们只是要防止线程进入同步代码区域中,所以lpName参数设置为nil。 3、在同步代码前用WaitForSingleObject()函数。该函数使得线程取得互斥对象(同步代码)的拥有权。该函数定义为: DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds); 这个函数可以使当前线程在dwMilliseconds指定的时间内睡眠,直到hHandle参数指定的对象进入发信号状态为止。一个互斥对象不再被线程拥有时,它就进入发信号状态。当一个进程要终止时,它就进入发信号状态。dwMilliseconds参数可以设为0,这意味着只检查hHandle参数指定的对象是否处于发信号状态,而后立即返回。dwMilliseconds参数设为INFINITE,表示如果信号不出现将一直等下去。 这个函数的返回值含义: WAIT_ABANDONED 指定的对象是互斥对象,并且拥有这个互斥对象的线程在没有释放此对象之前就已终止。此时就称互斥对象被抛弃。这种情况下,这个互斥对象归当前线程所有,并把它设为非发信号状态 WAIT_OBJECT_0 指定的对象处于发信号状态 WAIT_TIMEOUT 等待的时间已过,对象仍然是非发信号状态 再次声明,当一个互斥对象不再被一个线程所拥有,它就处于发信号状态。此时首先调用WaitForSingleObject()函数的线程就成为该互斥对象的拥有者,此互斥对象设为不发信号状态。当线程调用ReleaseMutex()函数并传递一个互斥对象的句柄作为参数时,这种拥有关系就被解除,互斥对象重新进入发信号状态。 注意除WaitForSingleObject()函数外,你还可以使用WaitForMultipleObject()和MsgWaitForMultipleObject()函数,它们可以等待几个对象变为发信号状态。这两个函数的详细情况请看Win32 API联机文档。 4、在同步代码结束后,使用ReleaseMutex(THandle)函数来标志。该函数只是释放互斥对象和线程的拥有者关系,并不释放互斥对象的句柄。 5、调用CloseHandle(THandle)来关闭互斥对象。请注意例程中该函数的使用位置。 三、还有一种用信号量对象来管理线程同步的,它是在互斥的基础上建立的,但信号量增加了资源计数的功能,预定数目的线程允许同时进入要同步的代码。有点复杂,想不到在哪可以用,现在就不研究论了。 unit Tst_Thread3U; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private procedure ThreadsDone(Sender: TObject); end; TMyThread=class(TThread) protected procedure Execute;override; end; var Form1: TForm1; implementation {$R *.dfm} const MaxSize=128; var NextNumber:Integer=0; DoneFlags:Integer=0; GlobalArry:array[1..MaxSize] of Integer; Lock:byte; //1-不同步 2-临界区 3-互斥 CS:TRTLCriticalSection; //临界区 hMutex:THandle; //互斥 function GetNextNumber:Integer; begin Result:=NextNumber; inc(NextNumber); end; procedure TMyThread.Execute; var i:Integer; begin FreeOnTerminate:=True; //终止后自动free OnTerminate:=Form1.ThreadsDone; if Lock3 then //非互斥情况 begin if Lock=2 then EnterCriticalSection(CS); //建立临界区 for i := 1 to MaxSize do begin GlobalArry[i]:=GetNextNumber; Sleep(5); end; if Lock=2 then LeaveCriticalSection(CS);//离开临界区 end else //-------互斥 begin if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then begin for i := 1 to MaxSize do begin GlobalArry[i]:=GetNextNumber; Sleep(5); end; end; ReleaseMutex(hMutex); //释放 end; end; procedure TForm1.ThreadsDone(Sender: TObject); var i:Integer; begin Inc(DoneFlags); if DoneFlags=2 then begin for i := 1 to MaxSize do Memo1.Lines.Add(inttostr(GlobalArry[i])); if Lock=2 then DeleteCriticalSection(CS); //删除临界区 If Lock=3 then CloseHandle(hMutex); //关闭互斥 end; end; //非同步 procedure TForm1.Button1Click(Sender: TObject); begin Lock:=1; TMyThread.Create(False); TMyThread.Create(False); end; //临界区 procedure TForm1.Button2Click(Sender: TObject); begin Lock:=2; InitializeCriticalSection(CS); //初始化临界区 TMyThread.Create(False); TMyThread.Create(False); end; //互斥 procedure TForm1.Button3Click(Sender: TObject); begin Lock:=3; // 互斥 hMutex:=CreateMutex(0,False,nil); TMyThread.Create(False); TMyThread.Create(False); end; end.

TCriticalSection 定义说明

定义(原文出处): https://www.freepascal.org/docs-html/fcl/syncobjs/tcriticalsection.html 一、定义 二、说明 TCriticalSection is a class wrapper around the low-level TRTLCriticalSection routines. It simply calls the RTL routines in the system unit for critical section su

zhy的博客 1197

【转】临界区对象TCriticalSection(Delphi) 与 TRtlCriticalSection 的区别

http://hi.baidu.com/twtynk1/blog/item/10e97715f19ef00b4a90a75b.html TRtlCriticalSection 是一个结构体,在windows单元中定义; 是InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection等这几个kernel32.dll中的

okmnji79513的专栏 3546

DELPHI跨平台的临界替代者

在WINDOWS里面使用临界来保护多线程需要访问的共享对象,现在,DELPHI有了新的跨平台临界保护者--System.TMonitor 代码演示如下: FConnections := TObjectDictionary<TIdTCPConnection,TDSTCPChannel>.Create; 。。。 procedure TCMServerForm.CMServerTra...

weixin_33863087的博客 229

delphi:临界区对象TCriticalSection(Delphi) 与 TRtlCriticalSection 的区别

临界区对象TCriticalSection(Delphi) 与 TRtlCriticalSection 的区别 TRtlCriticalSection 是一个结构体,在windows单元中定义; 是InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection, DeleteCriticalSection 等这几个kernel32.dll中的临界区操作API的参数; TCriticalSection是在SyncObjs单元中实现的类

jiangxmsoft的专栏 764

delphi临界

多线程程序中,如果各个线程要访问同一个资源,如同一个变量 这时就要使用线程同步技术,才不会使线程之间产生冲突和干扰 线程同步有多种办法,使用临界区是其中最简单,也是效率最高的办法(CPU占用时间最少) 使用临界区代码如下: 先声明一个TRTLCriticalSection类型的全局变量 var   MyCs:TRTLCriticalSection; 在程序开始

3486

delphi多线程访问公共变量

一、用TCriticalSection类来阻塞。(ps:这里的咚咚都涉及Win32编程,我对这些不了解,先掌握如何运用吧。)这个有点类似临界区。要Uses SyncObjs单元。1、声明一个全局的TCriticalSection类的实例。2、建立TCriticalSection.Create,最好是在程序onCreate里面,这样才能保证对所有线程进行控制。3、在全局变量访问前用TCriticalSection.Acquire或TCriticalSection.Enter来阻塞。4、访问完毕,用TCriti

互联网产品管理、交互、设计、开发、用户体验专栏 2449

临界区对象TCriticalSection(Delphi) 与 TRtlCriticalSection 的区别

TRtlCriticalSection 是一个结构体,在windows单元中定义;TCriticalSection是在SyncObjs单元中实现的类,它对上面的那些临界区操作API函数进行了了封装,简化并方便了在Delphi的使用; 如TCriticalSection.Enter,就是调用了EnterCriticalSection这个API函数。 多线程程序中,如果各个线程要访问同一个资源,如...

一叶知秋 2616

Delphi】中共享锁实现

如果对象不提供内置的锁定机制,则可以使用临界区。临界区的工作方式类似于允许单个线程在任何时刻进入的门。要使用临界区,创建一个。每个临界区都与您想要保护的全局内存相关联。每个访问该全局内存的线程在访问之前都应首先使用。:临界区仅在每个线程都使用它们来访问关联的全局内存时才有效。如果线程忽略临界区并在不调用。方法,以确保没有其他线程正在使用它。的情况下访问全局内存,可能会引入同时访问的问题。例如,考虑一个应用程序,它有一个全局临界区变量。(用于阻止其他线程执行该区域)和。方法,以便其他线程可以通过调用。

sensor_WU 博客 677

delphi xe 并行 多线程 队列 TCriticalSection TMutex TSpinlock TMonitor

直接上图:运行结果如下: 如 代码如下 : unit Unit5; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialog...

qq457565758的博客 2142
上一篇: delphi中Thread线程的使用方法
下一篇: Delphi中Interface接口的使用方法
delphi1234
博客等级 码龄24年 37粉丝 52原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值