此文章是vip文章,如何查看?  

1,点击链接获取密钥 http://nicethemes.cn/product/view29882.html

2,在下方输入文章查看密钥即可立即查看当前vip文章


delphi XE多线程同步对象及其管理

  • 时间:
  • 浏览:
  • 来源:互联网

delphi XE多线程同步对象及其管理

        本下载(以下面得代码为准)解决delphiXE在处理多线程时,如何对各线程进行管理、如何做到中途中断执行多线程时的线程安全,如何在多线程内部进行UI同步等等。

        直接上代码,自己看咯:

unit uMultiThreadSyncObjs;

interface

uses
  System.SysUtils,

  System.Types,
    //:任何一个应用系统自动加入的,其中含多线程同步等待及异步结果接口
  System.UITypes,
  System.Classes,
    //:任何一个应用系统自动加入的,其中含部分多线程类型的实现

  System.Variants,

  System.SyncObjs, //:需要用到多线程同步对象时

  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, FMX.ScrollBox, FMX.Memo;

type
  TfmxMultiThreadAndAsynResult = class(TForm)
    btnIAsyncResultAndMultiWaitEventIm: TButton;
    Text_Tips: TText;
    RectText_Tips: TRectangle;
    MetropolisUIBlue_touch: TStyleBook;
    Memo1: TMemo;

    ///<summary>用于并发测试的方法:</summary>
    procedure btnIAsyncResultAndMultiWaitEventImClick(Sender: TObject);
    ///<summary>用户退出窗体时,再次确认线程安全(因各线程内执行的任务太多、太快):</summary>
    procedure FormClose(Sender: TObject; var Action: TCloseAction);

  private

    ///<summary>多线程的标识及管理数组</summary>
    LThreads :TArray<TThread>;
    ///<summary>多线程的信号灯数组</summary>
    LEvents :TArray<TEvent>;

    { Private declarations }
  public
    { Public declarations }
  end;

var
  FRestTimeout:Integer =1000;
  fmxMultiThreadAndAsynResult: TfmxMultiThreadAndAsynResult;

implementation
  uses System.Math;
{$R *.fmx}

procedure TfmxMultiThreadAndAsynResult.btnIAsyncResultAndMultiWaitEventImClick(
  Sender: TObject);
//:用于并发测试的方法:
var
  LThreadCounts:Cardinal;
  LStopOrStart:ShortInt;
  LTest :Integer;
begin
  if btnIAsyncResultAndMultiWaitEventIm.Text.Trim='开始' then
  begin
    btnIAsyncResultAndMultiWaitEventIm.Text:='停止';
    LStopOrStart:=0;
  end else
  begin
    btnIAsyncResultAndMultiWaitEventIm.Text:='开始';
    LStopOrStart:=1;
  end;
  if LEvents=nil then
  begin
    SetLength(LEvents,51);  SetLength(LThreads,51);
      //:初始化多线程数组及其信号灯数组
  end;
  LTest :=0;

  for LThreadCounts := 1 to 50 do
  begin //:开50个单线程组成的多线程
    if LEvents[LThreadCounts]=nil then
      LEvents[LThreadCounts]:=TEvent.Create(false);
      //:为多线程中的每个线程设置其执行信号灯

    LThreads[LThreadCounts]:=  //:在这样来识别和管理匿名多线程(线程数组)
    TThread.CreateAnonymousThread(
      //:创建一个独立的匿名线程线程,在其中完成UI界面交互的同步过程
    procedure
      var LEventsCount: Cardinal;//:线程内的变量:
    begin //匿名线程的Excute代码:
      while true do  //:让每个匿名线程无限的并发测试下去:
      begin
        System.TMonitor.TryEnter(Sender);
        TThread.Sleep(FRestTimeout); //:模拟一个后台或远程服务器的耗时操作
          //:如果是返回远程服务器的响应对象祖先类为AObject,响应对象也需以下类似的方式同时释放掉
          //:同时响应对象用TMonitor.Enter(AObject);监视try 执行...Finally TMonitor.Exit(AObject);
        System.TMonitor.Exit(Sender);
        System.SyncObjs.TInterlocked.Increment(LTest);
        if LStopOrStart=0 then
        begin
          TThread.Synchronize(nil,
          procedure begin
            Text_Tips.Text:=LTest.ToString;
          end );
          if LEvents[LThreadCounts]<>nil then
          begin
            if LEvents[LThreadCounts].WaitFor(0)=TWaitResult.wrSignaled then
            begin
              LEvents[LEventsCount].SetEvent; //:点亮某线程的信号灯数组,停止该线程
              LEvents[LEventsCount].DisposeOf;//:信号灯数组中的该信号灯内存空间释放
            end;
          end;
        end;
        if LStopOrStart=1 then //:用户点停止,中断操作
        begin
          for LEventsCount := 1 to 50 do
          begin
            if LEvents[LEventsCount]<>nil then
            begin
              System.TMonitor.TryEnter(Text_Tips);
              if LEvents[LThreadCounts].WaitFor(0)=TWaitResult.wrTimeout then
                begin
                  LEvents[LEventsCount].SetEvent; //:点亮某线程的信号灯数组,停止该线程
                  LEvents[LEventsCount].DisposeOf;//:信号灯数组中的该信号灯内存空间释放
                end;
              end;
              System.TMonitor.Exit(Text_Tips);
          end;
          if LEvents<>nil then LEvents:=nil;  //:信号灯数组内存指针释放
          exit; //:停止执行
        end;
      end;
    end ); //:匿名线程预定义,非立即执行方式:
    //LThreads[LThreadCounts].FreeOnTerminate:=true;//:设定匿名多线程,中止时立即释放
    LThreads[LThreadCounts].Start; //:开始执行匿名的多线程
  end;

end;

procedure TfmxMultiThreadAndAsynResult.FormClose(Sender: TObject;
  var Action: TCloseAction);
var LThreadCounts:Cardinal;
begin
  //用户退出窗体时,再次确认线程安全(因各线程内执行的任务太多、太快):
  if LEvents<>nil then //:如果标识多线程的信号灯数组内存指针尚未得以释放
  begin
    System.TMonitor.TryEnter(self);
    for LThreadCounts := 1 to 50 do
    begin
      if LEvents[LThreadCounts]<>nil then
      begin
        if LEvents[LThreadCounts].WaitFor( Cardinal(Ceil(FRestTimeout*0.025)) )
          =TWaitResult.wrTimeout then
        begin
          //:Waitfor多长时间:根据CPU硅晶片信号量,约线程
            //:Excute或TNetHttpClient超时时间N的千分之23-26‰之间即可
            //:一般超时时间超过2000毫秒对用户就很不友好啦:可将其作为Timeout临界值Max
          //:取N* 25‰就好
          LEvents[LThreadCounts].SetEvent;   //:点亮某线程的信号灯数组,停止该线程
          LEvents[LThreadCounts].DisposeOf;  //:信号灯数组中的该信号灯内存空间释放
        end;

      end;
    end;
    LEvents:=nil;          //:信号灯数组释放内存指针(地址)
    LThreads:=nil;         //:多线程数组释放内存指针(地址)
    System.TMonitor.Exit(self);
  end;

  close;
end;

end.
program ProMultiThreadSyncObjs;

uses
  System.StartUpCopy,
  FMX.Forms,
  uMultiThreadSyncObjs in 'uMultiThreadSyncObjs.pas' {fmxMultiThreadAndAsynResult};

{$R *.res}

begin
  ReportMemoryLeaksOnShutdown := True; //:只要有内存泄漏就报

  Application.Initialize;
  Application.CreateForm(TfmxMultiThreadAndAsynResult, fmxMultiThreadAndAsynResult);
  Application.Run;
end.

1、大家都要好好学习delphi XE线程同步对象单元System.SyncObjs

        https://blog.csdn.net/pulledup/article/details/106136991

2、线程、多线程、同步执行、异步执行、并行相关内容参考

        https://blog.csdn.net/pulledup/article/details/105617706

喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:

本文链接http://element-ui.cn/news/show-577266.aspx