• 多线程编程(3) 多线程同步之 CriticalSection(临界区)


    "临界区"(CriticalSection): 当把一段代码放入一个临界区, 线程执行到临界区时就独占了, 让其他也要执行此代码的线程先等等; 这和前面用的 Lock 和 UnLock 差不多; 使用格式如下:

    var CS: TRTLCriticalSection;   {声明一个 TRTLCriticalSection 结构类型变量; 它应该是全局的}
    InitializeCriticalSection(CS); {初始化}
    EnterCriticalSection(CS);      {开始: 轮到我了其他线程走开}
    LeaveCriticalSection(CS);      {结束: 其他线程可以来了}
    DeleteCriticalSection(CS);     {删除: 注意不能过早删除}
    
    //也可用 TryEnterCriticalSection 替代 EnterCriticalSection.
    var
      CS: TRTLCriticalSection;
    
    function MyThreadFun(p: Pointer): DWORD; stdcall;
    var
      i: Integer;
    begin
      EnterCriticalSection(CS);
      for i := 0 to 99 do Form1.ListBox1.Items.Add(IntToStr(i));
      LeaveCriticalSection(CS);
      Result := 0;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      ID: DWORD;
    begin
      CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
      CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
      CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListBox1.Align := alLeft;
      InitializeCriticalSection(CS);
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      DeleteCriticalSection(CS);
    end;
    
    Delphi 在 SyncObjs 单元给封装了一个 TCriticalSection 类, 用法差不多
    uses SyncObjs;
    
    var
      CS: TCriticalSection;
    
    function MyThreadFun(p: Pointer): DWORD; stdcall;
    var
      i: Integer;
    begin
      CS.Enter;
      for i := 0 to 99 do Form1.ListBox1.Items.Add(IntToStr(i));
      CS.Leave;
      Result := 0;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      ID: DWORD;
    begin
      CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
      CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
      CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListBox1.Align := alLeft;
      CS := TCriticalSection.Create;
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      CS.Free;
    end;
    
  • 相关阅读:
    a标签去除默认样式
    js获取浏览器的get传值
    apache启动的时候报错非法协议
    获取iframe引入页面内的元素
    百度地图,画多边形后获取中心点
    echarts重写提示框信息,使提示框内的数字每3位以逗号分割
    echarts图例和图例文字位置的设置
    websocket socketJs
    winds添加静态路由
    pscp命令详解
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940723.html
Copyright © 2020-2023  润新知