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