博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于同一线程中临界区编程的

Posted on 2013-09-02 17:54  wlmbz  阅读(485)  评论(3编辑  收藏  举报
对于临界区,我常常在多线程编程中使用,来保护关键代码段,像下面的代码:

type
  TClient=class
  private
    FLock: TRTLCriticalSection;  
  public
    procedure Lock;  
    procedure UnLock;  
    constructor Create;   
    destructor Destroy; override;  
  end;  
             
implementation
               
procedure TClient.Lock;  
begin
  EnterCriticalSection(FLock);  
end;  
             
procedure TClient.UnLock;  
begin
  LeaveCriticalSection(FLock);  
end;  
             
constructor TClient.Create;  
begin
  InitializeCriticalSection(FLock);  
  inherited Create;  
end;  
             
destructor TClientSocket.Destroy;  
begin
  inherited;  
  DeleteCriticalSection(FLock);  
end;

但今天在使用Indy控件编程的时候,发现Lock函数并没有阻塞住,经过研究,发现:

只要程序界面加了 TIdAntiFreeze 控件,Timer1的事件过程就会重入。

事件的重入很好理解,因为Indy的TIdAntiFreeze控件,就是在Indy在执行阻塞操作时,在后台不断调用 Application.ProcessMessage,来处理消息,防止界面卡死。

但Lock并没有锁住关键代码段,即,代码在EnterCriticalSection(FLock)处并没有阻塞(已经执行了一次Lock,还没有执行UnLock的时候),经我反复测试发现,原来,

临界区锁,只对不同线程才保护关键代码段,同一线程的话,则根本不会锁的。

 

所以,我们在Delphi中编程的时候,要慎用 Application.ProcessMessage。

在Timer事件中,为防止重入,可以先禁用Timer,等事件函数执行完成后,在启用Timer,如:

Timer2.Enabled := False;
try  
  //你的代码  
finally
  Timer2.Enabled := True;
end;

  (Delphi编程感悟:wlmbz 20130701)