mormot.core.threads--TSynThread

mormot.core.threads--TSynThread

{ ************ 面向服务器进程的线程池 }

type
  {$M+} // 开启内存管理消息,用于调试

  /// 一个简单的TThread,具有在线程上下文中运行的"Terminate"事件
  // - TThread.OnTerminate事件在Synchronize()内部运行,因此不符合我们的期望,
  // 即在线程创建的上下文中释放资源(例如,对于COM对象或某些数据库驱动程序)
  // - 由THttpServerGeneric.NotifyThreadStart()内部使用 - 您不应该使用受保护的fOnThreadTerminate事件处理程序
  // - 还定义了一个Start方法,以与Delphi的旧版本兼容
  TSynThread = class(TThreadAbstract)
  protected
    fStartNotified: TObject; // 标记线程是否已通知开始
    // 我们定义了一个fOnThreadTerminate事件,该事件将在终止的线程上下文中运行
    // (而TThread.OnTerminate在主线程中调用)
    // -> 参见THttpServerGeneric.OnHttpThreadTerminate事件属性
    fOnThreadTerminate: TOnNotifyThread;
    procedure DoTerminate; override; // 重写DoTerminate方法
  public
    /// 初始化线程实例,处于非挂起状态
    constructor Create(CreateSuspended: boolean); reintroduce; virtual;
    /// Sleep的安全版本,不会中断线程进程
    // - 如果线程已终止,则返回TRUE
    // - 如果成功等待了MS毫秒,则返回FALSE
    function SleepOrTerminated(MS: cardinal): boolean;
    /// 确保仅在NotifyThreadStart完成后调用fOnThreadTerminate
    property StartNotified: TObject
      read fStartNotified write fStartNotified;
  end;

  /// 实现具有开始/停止通知功能的线程的抽象类
  // - 例如,服务器线程
  // - 不要使用这个类,而是使用THttpServer, THttpApiServer或TWebSocketServer(如mormot.net.websock中定义的)
  TNotifiedThread = class(TSynThread)
  protected
    fProcessName: RawUtf8; // 进程名称
    fOnThreadStart: TOnNotifyThread; // 线程开始通知事件
    procedure SetOnTerminate(const Event: TOnNotifyThread); virtual; // 设置线程终止事件
    procedure NotifyThreadStart(Sender: TSynThread); // 通知线程开始
  public
    /// 初始化服务器实例,处于非挂起状态
    constructor Create(CreateSuspended: boolean;
      const OnStart, OnStop: TOnNotifyThread; // 开始和停止通知事件
      const ProcessName: RawUtf8); reintroduce; virtual;
    /// 将每个线程分配给单个逻辑CPU核心
    // - 例如,对于HTTP服务器,它可能确保具有短生命周期请求和高线程数的更好的可扩展性
    procedure SetServerThreadsAffinityPerCpu(
      const log: ISynLog; const threads: TThreadDynArray);
    /// 将每个线程分配给单个硬件CPU插槽
    // - 例如,对于具有多个物理CPU包的复杂硬件上的HTTP服务器,它可能确保更好的可扩展性
    // - 但这非常挑剔,因此仅应在实际硬件上进行适当测试后才能启用
    procedure SetServerThreadsAffinityPerSocket(
      const log: ISynLog; const threads: TThreadDynArray);
  end;

  /// 实现具有日志通知功能的线程的抽象类
  TLoggedThread = class(TSynThread)
  protected
    fProcessName: RawUtf8; // 进程名称
    fLogClass: TSynLogClass; // 日志类
    fLog: TSynLog; // 在DoExecute线程上下文中的日志实例
    fProcessing: boolean; // 标记线程是否正在处理
    procedure Execute; override; // 重写Execute方法
    // 继承类应该重写此方法以实现适当的处理逻辑
    procedure DoExecute; virtual; abstract;
  public
    /// 初始化服务器实例,处于非挂起状态
    constructor Create(CreateSuspended: boolean; Logger: TSynLogClass;
      const ProcName: RawUtf8); reintroduce; virtual;
    /// 通知线程终止,并等待DoExecute完成
    procedure TerminateAndWaitFinished(TimeOutMs: integer = 5000); virtual;
    /// 关联的日志类
    property LogClass: TSynLogClass
      read fLogClass;
  published
    /// 此线程的名称,作为SetCurrentThreadName()的参数提供
    property ProcessName: RawUtf8
      read fProcessName;
  end;

  /// 在后台线程中由TLoggedWorkThread.Create调用的事件
  TOnLoggedWorkProcess = procedure(const Context: TDocVariantData) of object;

  /// 一个能够在后台线程中运行某些进程,并具有适当日志记录和最终通知功能的类
  TLoggedWorkThread = class(TLoggedThread)
  protected
    fSender: TObject; // 发送者对象
    fOnExecute, fOnExecuted: TNotifyEvent; // 执行前后的事件
    fOnExecuteParam: TOnLoggedWorkProcess; // 执行参数的事件
    fContext: TDocVariantData; // 上下文数据
    procedure DoExecute; override; // 重写DoExecute方法
  public
    /// 此构造函数将直接在后台启动线程
    // - 上下文作为常规的TNotifyEvent
    constructor Create(Logger: TSynLogClass; const ProcessName: RawUtf8;
      Sender: TObject; const OnExecute: TNotifyEvent;
      const OnExecuted: TNotifyEvent = nil);
        reintroduce; overload;
    /// 此构造函数将直接在后台启动线程
    // - 上下文作为具有名称/值对的TDocVariantData对象
    constructor Create(Logger: TSynLogClass; const ProcessName: RawUtf8;
      const NameValuePairs: array of const; const OnExecute: TOnLoggedWorkProcess;
      const OnExecuted: TNotifyEvent = nil);
        reintroduce; overload;
  end;

热门相关:捡宝王   战神无双   完美隐婚   金门大国铭   完美再遇