Delphi多线程学习(4):临界区


      临界区是一段代码,一次只允许一个线程执行这段代码。当把一段代码放入一个临界区, 线程执行到临界区时就独占了, 其他线程如果要访问这段代码,一定要等前一个访问的线程结束才行。借用前面的比喻比作图书馆,临界区就像把图书馆设计成只有一个位置(现实中好像不太合理,不管了,反正这么个意思),当有一个人正在办理业务时,其他人只能等待那个人办完业务才能进去。

    使用临界区的步骤:

    1、声明一个TRLCriticalSection记录类型的变量如CS,必须是全局的;

    2、使用前先初始化:InitializeCriticalSection(CS);

    3、EnterCriticalSection(CS);  线程进入临界区,其他线程需要等待

    4、LeaveCriticalSection(CS);  线程离开临界区,其他线程可以访问了

    5、DeleteCriticalSection(CS); 最后删除临界区

重写前文的例子,如下:

    {主窗体代码}  

  1. unit Unit2;  
  2.    
  3. interface  
  4.    
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, StdCtrls;  
  8.    
  9. type  
  10.   TForm2 = class(TForm)  
  11.     ListBox1: TListBox;  
  12.     Button1: TButton;  
  13.     procedure Button1Click(Sender: TObject);  
  14.     procedure FormCreate(Sender: TObject);  
  15.     procedure FormDestroy(Sender: TObject);  
  16.   private  
  17.     { Private declarations }  
  18.   public  
  19.     { Public declarations }  
  20.   end;  
  21.    
  22. var  
  23.   Form2: TForm2;  
  24.   CS:TRTLCriticalSection;  //全局临界区变量   
  25. implementation  
  26.    
  27. uses MyThread;  
  28.    
  29. {$R *.dfm}  
  30.    
  31. procedure TForm2.Button1Click(Sender: TObject);  
  32. begin  
  33.   TMyThread.Create(False);  
  34.   TMyThread.Create(False);  
  35.   TMyThread.Create(False);       
  36. end;  
  37.    
  38. procedure TForm2.FormCreate(Sender: TObject);  
  39. begin  
  40.   InitializeCriticalSection(CS);  //初始化   
  41. end;  
  42.    
  43. procedure TForm2.FormDestroy(Sender: TObject);  
  44. begin  
  45.   DeleteCriticalSection(CS);   //删除   
  46. end;  
  47.    
  48. end.{线程类}  
  49. unit MyThread;  
  50.    
  51. interface  
  52.    
  53. uses  
  54.   Classes,StdCtrls,SysUtils,Windows;  
  55.    
  56. type  
  57.   TMyThread = class(TThread)  
  58.   private  
  59.     { Private declarations }  
  60.     str:String;  
  61.     procedure AddList;  
  62.   protected  
  63.     procedure Execute; override;  
  64.   end;  
  65.    
  66. implementation  
  67.    
  68. uses Unit2;  
  69.    
  70. { TMyThread }  
  71.    
  72. procedure TMyThread.AddList;  
  73. begin  
  74.   Form2.ListBox1.Items.Add(str);  
  75. end;  
  76.    
  77. procedure TMyThread.Execute;  
  78. var  
  79.   i:Integer;  
  80. begin  
  81.   { Place thread code here }  
  82.   FreeOnTerminate:=True;  
  83.   EnterCriticalSection(CS);    //进入临界区   
  84.   try  
  85.     for i := 0 to 99 do  
  86.       begin  
  87.         if not Terminated then  
  88.           begin  
  89.             str:=Format('线程ID:%.4d,第%.2d个循环。',[GetCurrentThreadId,i]);  
  90.             Synchronize(AddList);  
  91.           end;  
  92.       end;  
  93.   finally  
  94.     LeaveCriticalSection(CS);  //离开临界区   
  95.   end;  
  96. end;  
  97.    
  98. end.  

 

OK,可以看到线程是依次执行的了。

临界区只用于进程内,是相当轻量级的,当没有线程冲突时,进入或离开临界区大概只需要10到20个时钟周期


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM