mormot.core.threads--TSynThread
海利鸟 2024-07-09 08:39:00 阅读 76
mormot.core.threads--TSynThread
<code>{ ************ 面向服务器进程的线程池 }
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;
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。