倒底怎么用,能不能举例

解决方案 »

  1.   


    {所谓临界区,就是一次只能由一个线程来执行的一段代码。如果把初始化数组的代码放在临界区内,另一个线程在第一个线程处理完之前是不会被执行的。
    使用临界区的步骤:
    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);后,会产生错误。
    }
    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 Lock<>3 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.
      

  2.   

    跟互斥量是一个用途
    互斥量:占用资源较多、速度较慢、系统资源、命名对象、可跨进程使用
    临界区:占用资源较少、速度较快、进程资源、进程内使用简单来说就是一个标记,标志是否有线程在使用某个资源。
    每个线程要使用这个资源就要把标志设置为True,当使用完毕之后就把它设置为False。而当标志本来就是True的时候就没法再设置为Ture,一直等待,直到等到它变为False后才能再次设置为True。
      

  3.   

    一楼的例子不错,建议楼主下个 <delphi 5开发人员指南>看看  里面有详细讲解,还有实例.