[原创][Delphi多线程]使用TMonitor, TEvent和TQueue配合实现TThreadQueue的经典使用案例.

[简介]

常用网名: 猪头三

出生日期: 1981.XX.XX

QQ: 643439947

个人网站: 80x86汇编小站 https://www.x86asm.org

编程生涯: 2001年~至今[共22年]

职业生涯: 20年

开发语言: C/C++、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python

开发工具: Visual Studio、Delphi、XCode、Eclipse、C++ Builder

技能种类: 逆向 驱动 磁盘 文件

研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全/macOS应用软件安全

项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测

[序言]

本次内容主要是学习TMonitor, TEvent和TQueue配合实现TThreadQueue的经典使用案例. 本次代码的同步等待机制是使用TEvent的WaitFor(), SetEvent()和ResetEvent()方法.

[下面是经典代码]

Delphi 复制代码
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes, System.Threading, System.SyncObjs,
  System.Generics.Collections,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Bn_ReadThread: TButton;
    Bn_WriteThread: TButton;
    Memo_Result: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Bn_ReadThreadClick(Sender: TObject);
    procedure Bn_WriteThreadClick(Sender: TObject);
  private
    { Private declarations }

    mpr_ShareQueue   : TQueue<string> ; // 共享数据队列
    mpr_Thread_Lock  : TObject ;        // 同步锁
    mpr_Thread_event : TEvent  ;        // 同步事件

    mpr_Threads_Count: Integer ;        // 写者线程的数量

  public
    { Public declarations }
    procedure mpu_pro_Thread_Write(const cstr_param_Data : string) ;

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin

  mpr_ShareQueue   := TQueue<string>.Create() ;
  mpr_Thread_Lock  := TObject.Create();

  mpr_Threads_Count := 0 ;

  // 同步事件初始化: 手工设置信号, 初始化为非信号状态
  mpr_Thread_event := TEvent.Create(nil, True, False,' ') ;

end;// End FormCreate()



procedure TForm1.FormShow(Sender: TObject);
begin
//
end;// End FormShow()



// 单个读者线程
procedure TForm1.Bn_ReadThreadClick(Sender: TObject);
begin

  TTask.Run(procedure
  var
    str_Data : string ;
  begin

    // 循环读取
    while True do
    begin

      // 等待共享数据队列存储新的数据
      mpr_Thread_event.WaitFor(INFINITE) ;

      // 启动同步锁
      System.TMonitor.Enter(mpr_Thread_Lock) ;
      try

        // 获取数据之后, 同步在界面上显式
        if mpr_ShareQueue.Count > 0 then
        begin

          str_Data := mpr_ShareQueue.Dequeue ;

          // 如果共享数据队列没有数据, 那么则通知读者线程进入等待状态
          if mpr_ShareQueue.Count = 0 then
          begin
            mpr_Thread_event.ResetEvent() ;
          end;

          // 界面显式数据
          TThread.Synchronize(TThread.Current, procedure
          begin
            Memo_Result.Lines.Add(str_Data) ;
          end);

        end;

      finally
        System.TMonitor.Exit(mpr_Thread_Lock) ;
      end;

    end;

  end);

end;// End Bn_ReadThreadClick()



procedure TForm1.mpu_pro_Thread_Write(const cstr_param_Data : string) ;
begin

  TTask.Run(procedure
  begin

    // 随机休眠时间
    TThread.Sleep((Random(5)+1)*1000) ;

    // 向共享数据队列添加数据
    // 启动同步锁
    System.TMonitor.Enter(mpr_Thread_Lock) ;
    try

      mpr_ShareQueue.Enqueue(cstr_param_Data) ;

      // 向读者线程发出信号, 共享数据队列有新数据进入
      mpr_Thread_event.SetEvent();

    finally
      System.TMonitor.Exit(mpr_Thread_Lock) ;
    end;

  end);

end;// End mpu_pro_Thread_Write()
procedure TForm1.Bn_WriteThreadClick(Sender: TObject);
var
  str_Data : string ;
begin

  Inc(mpr_Threads_Count) ;


  str_Data := Format('%d 号线程的数据.', [mpr_Threads_Count]) ;
  Bn_WriteThread.Caption := Format('2: 创建写入线程(%d)', [mpr_Threads_Count]) ;

  mpu_pro_Thread_Write(str_Data) ;

end;// End Bn_WriteThreadClick()


end.

[结尾]

上面的代码, 需要注意的细节是: TEvent的WaitFor(), SetEvent()和ResetEvent()替换了TMonitor.Wait()和TMonitor.Pulse()的等待与唤醒同步操作.

相关推荐
Da Da 泓3 小时前
多线程(四)【线程安全问题】
java·开发语言·jvm·学习·安全·多线程·线程安全问题
Brookty5 小时前
Java并发编程核心的基础知识
java·开发语言·java-ee·多线程·线程安全
羑悻的小杀马特2 天前
C++多线程同步工具箱:call_once精准触发、lock_guard/unique_lock智能管理,打造无死锁程序!
c++·多线程·死锁·lock_guard·unique_lock·call_once
武藤一雄4 天前
C# 万字拆解线程间通讯?
后端·微软·c#·.net·.netcore·多线程
萧曵 丶5 天前
CompletableFuture 实际场景使用案例
java·多线程·并发编程·高级开发
萧曵 丶5 天前
CompletableFuture 底层原理详解
java·jvm·多线程·并发编程
自然数e6 天前
c++多线程【基于锁的数据结构】
数据结构·c++·多线程
黑客思维者7 天前
Python 3.14(2025最新版)的核心语法特性分析
服务器·开发语言·python·多线程
BestOrNothing_201511 天前
C++ 并发四件套:并发编程 / 原子性 / 数据竞争 / 内存模型 (全解析)
c++·多线程·并发编程·线程安全·内存模型·原子操作·数据竞争
7澄112 天前
Java Socket 网络编程实战:从基础通信到线程池优化
java·服务器·网络·网络编程·socket·多线程·客户端