mormot.core.threads.pas unit

海利鸟發表於2024-06-11

mormot.core.threads.pas unit

Purpose: Framework Core Multi-Threading Support
- this unit is a part of the Open Source Synopse mORMot framework 2, licensed under a MPL/GPL/LGPL three license - see LICENSE.md

目的:框架核心多執行緒支援

  • 本單元是開源Synopse mORMot框架2的一部分,根據MPL/GPL/LGPL三重許可進行許可-參見LICENSE.md

1.1. Units used in the mormot.core.threads unit (在mormot.core.threads單元中使用的單元)

Unit Name Description
mormot.core.base Framework Core Shared Types and RTL-like Functions 框架核心共享型別和類似RTL的函式
mormot.core.buffers Framework Core Low-Level Memory Buffer Process 框架核心低階記憶體緩衝區處理
mormot.core.data Framework Core Low-Level Data Processing Functions 框架核心低階資料處理函式
mormot.core.json Framework Core Low-Level JSON Processing 框架核心低階JSON處理
mormot.core.log Framework Core Logging 框架核心日誌記錄
mormot.core.os Framework Core Low-Level Wrappers to the Operating-System API 框架核心對作業系統API的低階包裝器
mormot.core.perf Framework Core Performance and Monitoring Classes 框架核心效能和監視類
mormot.core.rtti Framework Core Low-Level Cross-Compiler RTTI Definitions 框架核心低階跨編譯器RTTI定義
mormot.core.text Framework Core Low-Level Text Processing 框架核心低階文字處理
mormot.core.unicode Framework Core Low-Level Unicode UTF-8 UTF-16 Ansi Conversion 框架核心低階Unicode UTF-8 UTF-16 Ansi轉換
mormot.core.variants Framework Core Low-Level Variants / TDocVariant process 框架核心低階變數/TDocVariant處理

1.2. mormot.core.threads class hierarchy

TSynThread
TSynThreadPoolWorkThread
TNotifiedThreadTLoggedThread
TLoggedWorkThreadTThreadAbstract
TSynBackgroundThreadAbstract
TSynBackgroundThreadProcess
TSynBackgroundTimer
TSynBackgroundThreadMethodAbstract
TSynParallelProcessThread
TSynBackgroundThreadProcedure
TSynBackgroundThreadMethod
TSynBackgroundThreadEventTThread
TSynPersistentStoreTSynQueue
TSynPersistentLockTSynParallelProcess
TSynPersistent
TBlockingProcessPool
TBlockingProcess
TBlockingProcessPoolItem
TSynEventTObject
TSynThreadPool
TPendingTaskList
TInterfacedObjectWithCustomCreate
TLockedDocVariantIInterface
ILockedDocVariant
ESynException
ESynThread

mormot.core.threads class hierarchy

image

1.3. Objects implemented in the mormot.core.threads unit (mormot.core.threads 單元中實現的物件)

Objects Description
ESynThread Exception class raised by this unit 由本單元引發的異常類
ILockedDocVariant Ref-counted interface for thread-safe access to a TDocVariant document 用於執行緒安全訪問TDocVariant文件的引用計數介面
TBlockingProcess A semaphore used to wait for some process to be finished 一個計數訊號量,用於等待某個程序完成
TBlockingProcessPool Manage a pool of TBlockingProcessPoolItem instances 管理一組TBlockingProcessPoolItem例項
TBlockingProcessPoolItem A semaphore used in the TBlockingProcessPool 在TBlockingProcessPool中使用的計數訊號量
TLockedDocVariant Allows thread-safe access to a TDocVariant document 允許執行緒安全地訪問TDocVariant文件
TLoggedThread Abstract class to implement a thread with logging notifications 實現帶有日誌通知的執行緒的抽象類
TLoggedWorkThread A class able to run some process in a background thread 能夠在後臺執行緒中執行某些程序的類
TNotifiedThread Abstract class to implement a thread with start/stop notifications 實現帶有啟動/停止通知的執行緒的抽象類
TPendingTaskList Thread-safe list of tasks, stored as RawByteString, with a timestamp 執行緒安全的任務列表,以RawByteString形式儲存,帶有時間戳
TPendingTaskListItem Internal item definition, used by TPendingTaskList storage TPendingTaskList儲存的內部專案定義
TSynBackgroundThreadAbstract Abstract TThread with its own execution content 帶有自己的執行內容的TThreadAbstract
TSynBackgroundThreadEvent Allow background thread process of a method callback 允許在後臺執行緒中處理方法回撥
TSynBackgroundThreadMethod Allow background thread process of a variable TThreadMethod callback 允許在後臺執行緒中處理可變TThreadMethod回撥
TSynBackgroundThreadMethodAbstract Abstract TThread able to run a method in its own execution content 能夠在自己的執行內容中執行方法的抽象TThread
TSynBackgroundThreadProcedure Allow background thread process of a procedure callback 允許在後臺執行緒中處理過程回撥
TSynBackgroundThreadProcess TThread able to run a method at a given periodic pace 能夠在給定週期速率下執行方法的TThread
TSynBackgroundTimer TThread able to run one or several tasks at a periodic pace in a background thread 能夠在後臺執行緒中以週期速率執行一個或多個任務的TThread
TSynBackgroundTimerTask Used by TSynBackgroundTimer internal registration list 用於TSynBackgroundTimer內部註冊列表
TSynParallelProcess Allow parallel execution of an index-based process in a thread pool 允許線上程池中並行執行基於索引的程序
TSynParallelProcessThread Thread executing process for TSynParallelProcess 為TSynParallelProcess執行程序的執行緒
TSynQueue Thread-safe FIFO (First-In-First-Out) in-order queue of records 執行緒安全的FIFO(先入先出)有序記錄佇列
TSynThread A simple TThread with a "Terminate" event run in the thread context 一個簡單的TThread,帶有線上程上下文中執行的"Terminate"事件
TSynThreadPool A simple Thread Pool, used e.g. for fast handling HTTP/1.0 requests 一個簡單的執行緒池,例如用於快速處理HTTP/1.0請求
TSynThreadPoolWorkThread Defines the work threads used by TSynThreadPool 定義TSynThreadPool使用的工作執行緒
TThreadAbstract Abstract parent of all TThread inherited classes 所有TThread繼承類的抽象父類

1.3.1. ESynThread

ESynThread = class(ESynException)

本單元引發的異常類


1.3.2. TSynQueue

TSynQueue = class(TSynPersistentStore)

*執行緒安全的FIFO(先入先出)記錄有序佇列

  • 內部使用TDynArray儲存,具有滑動演算法,比FPC或Delphi的TQueue或簡單的TDynArray.Add/Delete更高效
  • 如果需要,支援TSynPersistentStore二進位制持久化
  • 該結構在設計上也是執行緒安全的*

constructor Create(aTypeInfo: PRttiInfo; const aName: RawUtf8 = ''); reintroduce; virtual;

*初始化佇列儲存

  • aTypeInfo應是一個動態陣列的TypeInfo() RTTI指標,它將在這個TSynQueue例項中儲存值
  • 可以為這個例項可選地分配一個名稱*

destructor Destroy; override;

*銷燬儲存

  • 將釋放所有內部儲存的值,並呼叫WaitPopFinalize*

function Capacity: integer;

*返回當前在記憶體中預留的槽位數

  • 佇列具有最佳化的自動調整大小演算法,可以使用此方法返回其當前capacity
  • 此方法不是執行緒安全的,因此返回的值僅具有指示性*

function Count: integer;

*返回當前儲存在此佇列中的項數

  • 此方法不是執行緒安全的,因此返回的值要麼具有指示性,要麼應使用顯式的安全鎖定/解鎖
  • 如果要檢查佇列是否為空,請呼叫Pending*

function Peek(out aValue): boolean;

*從佇列中按FIFO(先入先出)方式查詢一個項

  • 如果aValue已被填充了一個pending項,而不從佇列中刪除它(如Pop方法所做的),則返回true
  • 如果佇列為空,則返回false
  • 此方法是執行緒安全的,因為它將鎖定例項*

function Pending: boolean;

*如果佇列中有一些當前pending的項,則返回true

  • 比檢查Count=0更快,並且比PopPeek快得多
  • 此方法不是執行緒安全的,因此返回的值僅具有指示性*

function Pop(out aValue): boolean;

*從佇列中按FIFO(先入先出)方式提取一個項

  • 如果aValue已被填充了一個pending項,並且該項已從佇列中刪除(如果不想刪除它,請使用Peek),則返回true
  • 如果佇列為空,則返回false
  • 此方法是執行緒安全的,因為它將鎖定例項*

function PopEquals(aAnother: pointer; aCompare: TDynArraySortCompare; out aValue): boolean;

*從佇列中按FIFO(先入先出)方式提取一個匹配的項

  • 當前pending項與aAnother值進行比較*

function WaitPeekLocked(aTimeoutMS: integer; const aWhenIdle: TThreadMethod): pointer;

*等待從佇列中按FIFO(先入先出)方式查詢一個項

  • 在aTimeoutMS時間內返回一個指向pending項的指標
  • 保持Safe.ReadWriteLock,因此呼叫者可以檢查其內容,然後如果它是預期的項,則呼叫Pop(),並最終呼叫Safe.ReadWriteUnlock
  • 如果在時間內沒有將任何內容推入佇列,則返回nil
  • 此方法是執行緒安全的,但僅在需要時鎖定例項*

function WaitPop(aTimeoutMS: integer; const aWhenIdle: TThreadMethod; out aValue; aCompared: pointer = nil; aCompare: TDynArraySortCompare = nil): boolean;

*等待並從佇列中按FIFO(先入先出)方式提取一個項

  • 如果在指定的aTimeoutMS時間內aValue已被填充了一個pending項,則返回true
  • 如果在時間內沒有將任何內容推入佇列,或者已呼叫WaitPopFinalize,則返回false
  • aWhenIdle可以被分配,例如給VCL/LCL Application.ProcessMessages
  • 可以在返回之前可選地比較pending項(例如,當多個執行緒將項放入佇列時可以使用)
  • 此方法是執行緒安全的,但僅在需要時鎖定例項*

procedure Clear;

*刪除當前儲存在此佇列中的所有項,並清空其capacity

  • 此方法是執行緒安全的,因為它將鎖定例項*

procedure Push(const aValue);

*將一個項儲存到佇列中

  • 此方法是執行緒安全的,因為它將鎖定例項*

procedure Save(out aDynArrayValues; aDynArray: PDynArray = nil); overload;

*使用儲存的佇列項初始化一個動態陣列

  • aDynArrayValues應是一個在Create中定義的aTypeInfo變數
  • 可以檢索一個可選的TDynArray包裝器,例如用於二進位制或JSON持久化
  • 此方法是執行緒安全的,並將複製佇列資料*

procedure WaitPopFinalize(aTimeoutMS: integer = 100);

*確保任何pending或未來的WaitPop()方法立即返回false

  • 總是由Destroy解構函式呼叫
  • 也可以從UI的OnClose事件中呼叫,以避免任何鎖定
  • 此方法是執行緒安全的,但僅在需要時鎖定例項*

1.3.3. TPendingTaskListItem

TPendingTaskListItem = packed record

內部專案定義,由TPendingTaskList儲存使用


Task: RawByteString;

相關聯的task,以原始二進位制形式儲存


Timestamp: Int64;

當TPendingTaskList.GetTimestamp達到此值時,應執行task


1.3.4. TPendingTaskList

TPendingTaskList = class(TObject)

*執行緒安全的任務列表,以RawByteString形式儲存,並帶有時間戳

  • 你可以向內部列表新增任務,以在給定延遲後執行,使用類似於post/peek的演算法
  • 執行延遲預計不準確,但根據每次NextPendingTask呼叫和GetTimestamp解析度進行最佳猜測*

constructor Create; reintroduce;

預設返回GetTickCount64來初始化列表記憶體和資源


function NextPendingTask: RawByteString; virtual;

*檢索下一個待處理task

  • 如果當前沒有計劃中的task,則返回''
  • 返回與指定延遲相對應的下一個堆疊*

procedure AddTask(aMilliSecondsDelayFromNow: integer; const aTask: RawByteString); virtual;

從當前時間開始,指定毫秒延遲後Append一個task


procedure AddTasks(const aMilliSecondsDelays: array of integer; const aTasks: array of RawByteString);

*指定任務之間的毫秒延遲後Append多個任務

  • 第一個提供的延遲將從當前時間開始計算,然後它將指定等待下一個提供task需要多長時間——也就是說,aMilliSecondsDelays不是絕對延遲*

procedure Clear; virtual;

清除所有待處理任務


property Count: integer read GetCount;

當前定義了多少個待處理任務


property Task: TPendingTaskListItemDynArray read fTask;

*直接低階訪問內部task列表

  • 警告:此動態陣列的長度是列表容量:請使用Count屬性來檢索儲存的確切項數
  • 使用try ... finally Safe.Unlock塊中的Safe.Lock/TryLock進行執行緒安全訪問此陣列
  • 專案按遞增的Timestamp儲存,即第一個專案是NextPendingTask方法將返回的下一個專案*

property Timestamp: Int64 read GetTimestamp;

*訪問內部TPendingTaskListItem.Timestamp儲存的值

  • 對應當前時間
  • 預設實現是返回GetTickCount64,在Windows下典型解析度為16毫秒*

1.3.5. ILockedDocVariant

ILockedDocVariant = interface(IInterface)

*用於執行緒安全訪問TDocVariant文件的引用計數介面

  • 例如,由TLockedDocVariant實現,用於IoC/DI解析
  • 快速且安全地儲存任何類似JSON的物件,作為屬性/值對,或類似JSON的陣列,作為值*

function AddExistingProp(const Name: RawUtf8; var Obj: variant): boolean;

*將現有屬性value新增到給定的TDocVariant文件物件

  • 如果Name存在,則返回TRUE並將Name/Value對新增到Obj
  • 如果儲存的文件中不存在Name,則返回FALSE
  • 此方法在查詢Name期間會使用lock,但無論是否返回FALSE,總是會釋放lock(參見AddExistingPropOrLock)*

function AddExistingPropOrLock(const Name: RawUtf8; var Obj: variant): boolean;

*將現有屬性value新增到給定的TDocVariant文件物件

  • 如果Name存在,則返回TRUE並將Name/Value對新增到Obj,使用內部lock確保執行緒安全
  • 如果儲存的文件中不存在Name,則返回FALSE並鎖定內部儲存:呼叫者最終應透過AddNewPropAndUnlock()釋放lock
  • 可以這樣使用,以實現執行緒安全的快取:
if not cache.AddExistingPropOrLock('Articles',Scope) then
  cache.AddNewPropAndUnlock('Articles',GetArticlesFromDB,Scope);

這裡GetArticlesFromDB會在主要lock內部執行


function Copy: variant;

對內部TDocVariant文件物件或陣列進行執行緒安全的複製


function Exists(const Name: RawUtf8; out Value: Variant): boolean;

*按名稱檢查和返回一個給定的屬性

  • 如果找到Name,則返回TRUE並將與提供的Name相關聯的value填充到Value中,使用內部lock確保執行緒安全
  • 如果未找到Name,則返回FALSE並釋放內部lock:如果你想要新增缺失的value,請使用ExistsOrLock()*

function ExistsOrLock(const Name: RawUtf8; out Value: Variant): boolean;

*按名稱檢查和返回一個給定的屬性

  • 如果找到Name,則返回TRUE並將與提供的Name相關聯的value填充到Value中,使用內部lock確保執行緒安全
  • 如果Name不存在,則返回FALSE並設定內部lock:呼叫者隨後應透過ReplaceAndUnlock()釋放lock*

function Lock: TAutoLocker;

對關聯的執行緒安全互斥鎖進行低階訪問


function ToJson(HumanReadable: boolean = false): RawUtf8;

將儲存的值儲存為UTF-8編碼的JSON物件


procedure AddItem(const Value: variant);

*將value新增到內部TDocVariant文件陣列

  • 不應與其他基於文件的替代方案(如Exists/AddExistingPropOrLockAddExistingProp)結合使用*

procedure AddNewProp(const Name: RawUtf8; const Value: variant; var Obj: variant);

*將屬性value新增到給定的TDocVariant文件物件

  • 此方法在呼叫時不會期望資源被鎖定,與AddNewPropAndUnlock不同
  • 將使用內部lock確保執行緒安全
  • 如果Name已存在,將更新/更改現有的value
  • 可以這樣使用,以實現執行緒安全的快取:
if not cache.AddExistingProp('Articles',Scope) then
  cache.AddNewProp('Articles',GetArticlesFromDB,Scope);

這裡GetArticlesFromDB會在主lock之外執行


procedure AddNewPropAndUnlock(const Name: RawUtf8; const Value: variant; var Obj: variant);

*將屬性value新增到給定的TDocVariant文件物件以及內部儲存的文件,然後釋放之前的lock

  • 呼叫此方法之前應由AddExistingPropOrLock()返回false,即在一個已鎖定的例項上執行*

procedure Clear;

刪除所有儲存的屬性


procedure ReplaceAndUnlock(const Name: RawUtf8; const Value: Variant; out LocalValue: Variant);

*透過屬性名稱設定value,並設定本地副本

  • 可以這樣使用,以實現執行緒安全的快取:
if not cache.ExistsOrLock('prop',local) then
  cache.ReplaceAndUnlock('prop',newValue,local);
  • 呼叫此方法之前應由ExistsOrLock()返回false,即在一個已鎖定的例項上執行

property Value[const Name: RawUtf8]: Variant read GetValue write SetValue;

*透過此屬性安全地訪問文件欄位

  • 這是此儲存的主要入口點
  • 如果在讀取時Name不存在,將引發EDocVariant異常
  • 實現類將對variant value進行執行緒安全的副本*

1.3.6. TLockedDocVariant

TLockedDocVariant = class(TInterfacedObjectWithCustomCreate)

*允許執行緒安全地訪問TDocVariant文件

  • 此類從TInterfacedObjectWithCustomCreate繼承,因此您可以定義一個mormot.core.interfaces.pas TInjectableObject的已釋出屬性為ILockedDocVariant,以便此類可以自動注入*

constructor Create(options: TDocVariantOptions); reintroduce; overload;

使用相應的選項初始化執行緒安全的文件儲存


constructor Create(options: TDocVariantModel); reintroduce; overload;

從給定的模板初始化執行緒安全的文件儲存


constructor Create; overload; override;

*使用快速的TDocVariant初始化執行緒安全的文件

  • 即呼叫Create(true)或Create(JSON_FAST)
  • 這將是TInterfacedObjectWithCustomCreate的預設建構函式,例如在IoC/DI解析期間呼叫*

destructor Destroy; override;

銷燬儲存


function AddExistingProp(const Name: RawUtf8; var Obj: variant): boolean;

*向給定的TDocVariant文件物件新增一個已存在的屬性value

  • 如果Name存在,則返回TRUE並將Name/Value對新增到Obj
  • 如果儲存的文件中不存在Name,則返回FALSE
  • 此方法在查詢Name期間會使用lock,但無論是否返回FALSE,總是會釋放lock(參見AddExistingPropOrLock)*

function AddExistingPropOrLock(const Name: RawUtf8; var Obj: variant): boolean;

*向給定的TDocVariant文件物件新增一個已存在的屬性value

  • 如果Name存在,則返回TRUE並將Name/Value對新增到Obj
  • 如果儲存的文件中不存在Name,則返回FALSE,並期望最終呼叫Lock.Leave或AddNewPropAndUnlock()

function Copy: variant;

對內部TDocVariant文件物件或陣列進行執行緒安全的複製


function Exists(const Name: RawUtf8; out Value: Variant): boolean;

按名稱檢查和返回一個給定的屬性


function ExistsOrLock(const Name: RawUtf8; out Value: Variant): boolean;

*按名稱檢查和返回一個給定的屬性

  • 如果找到,則返回TRUE並返回現有Name的value
  • 如果未找到,則返回FALSE,並期望最終呼叫Lock.Leave或ReplaceAndUnlock()

function Lock: TAutoLocker;

對關聯的執行緒安全互斥鎖進行低階訪問


function ToJson(HumanReadable: boolean = false): RawUtf8;

*將儲存的value儲存為UTF-8編碼的JSON物件

  • 僅僅是VariantSaveJson()的包裝*

procedure AddItem(const Value: variant);

value新增到內部TDocVariant文件陣列


procedure AddNewProp(const Name: RawUtf8; const Value: variant; var Obj: variant);

*向給定的TDocVariant文件物件新增一個屬性value

  • 此方法在呼叫時不會期望資源被鎖定,與AddNewPropAndUnlock不同
  • 將使用內部lock確保執行緒安全
  • 如果Name已存在,將更新/更改現有的value*

procedure AddNewPropAndUnlock(const Name: RawUtf8; const Value: variant; var Obj: variant);

向給定的TDocVariant文件物件和內部儲存的文件新增一個屬性value


procedure Clear;

刪除所有儲存的屬性


procedure ReplaceAndUnlock(const Name: RawUtf8; const Value: Variant; out LocalValue: Variant);

透過屬性名稱設定value,並設定本地副本


property Value[const Name: RawUtf8]: variant read GetValue write SetValue;

*將透過此屬性安全地訪問文件欄位

  • 如果Name不存在,將引發EDocVariant異常
  • 返回的variant結果是副本,不是varByRef,因為副本將更具執行緒安全性*

1.3.7. TThreadAbstract

TThreadAbstract = class(TThread)

*所有TThread繼承類的抽象父類

  • 利用跨編譯器和跨版本RTL的差異
  • 擁有預期的Start和TerminateSet方法,以及Terminated屬性*

procedure Start;

*呼叫此方法以start執行緒

  • Resume在最新的RTL中已被棄用,因為一些作業系統(例如Linux)沒有實現此暫停/恢復功能;我們在此為Delphi的舊版本定義此方法*

procedure Terminate; reintroduce;

重新引入以呼叫TerminatedSet


procedure TerminatedSet; virtual;

*正確terminate執行緒

  • 由重新引入的Terminate呼叫*

property Terminated;

定義為public,因為可能用於terminate處理方法


1.3.8. TSynBackgroundThreadAbstract

TSynBackgroundThreadAbstract = class(TThreadAbstract)

*具有自身執行內容的抽象TThread

  • 不應直接使用此類,而應使用TSynBackgroundThreadMethodAbstract / TSynBackgroundThreadEvent / TSynBackgroundThreadMethod,並提供更方便的回撥*

constructor Create(const aThreadName: RawUtf8; const OnBeforeExecute: TOnNotifyThread = nil; const OnAfterExecute: TOnNotifyThread = nil; CreateSuspended: boolean = false); reintroduce;

*初始化執行緒

  • 可以定義一些回撥來巢狀執行緒執行,例如分配給TRestServer.BeginCurrentThread/EndCurrentThread,或者至少將OnAfterExecute設定為TSynLogFamily.OnThreadEnded*

destructor Destroy; override;

*釋放使用的資源

  • 呼叫WaitForNotExecuting(100)以確保正確終結*

function SleepOrTerminated(MS: cardinal): boolean;

*Sleep()的安全版本,不會中斷執行緒程序

  • 如果執行緒已終止,則返回TRUE
  • 如果成功等待了MS毫秒,則返回FALSE*

procedure TerminatedSet; override;

*正確終止執行緒

  • 由重新引入的Terminate呼叫*

procedure WaitForNotExecuting(maxMS: integer = 500);

*等待Execute/ExecuteLoop結束(即fExecute<>exRun)

  • 在迴圈中呼叫Sleep(),直到達到超時
  • 例如在Destroy中使用,以避免任何GPF並確保乾淨地終結*

property Pause: boolean read fExecuteLoopPause write SetExecuteLoopPause;

*臨時停止ExecuteLoop的執行,直到設定為false

  • 例如可由TSynBackgroundTimer使用,以延遲後臺任務的程序*

property ProcessEvent: TSynEvent read fProcessEvent;

*訪問與低階別相關的事件,用於通知後臺執行緒任務執行

  • 可以呼叫ProcessEvent.SetEvent來觸發內部處理迴圈*


1.3.9. TSynBackgroundThreadMethodAbstract

TSynBackgroundThreadMethodAbstract = class(TSynBackgroundThreadAbstract)

*抽象TThread,能夠在其自己的執行內容中執行方法

  • 典型用途是用於處理資料或遠端訪問的後臺執行緒,同時UI將保持響應,透過在迴圈中執行OnIdle事件:例如,檢視mormot.rest.client.pas單元中TRestClientUri.OnIdle如何處理這種情況
  • 不應直接使用此類,而應從中繼承並重寫Process方法,或使用TSynBackgroundThreadEvent / TSynBackgroundThreadMethod並提供更方便的回撥*

constructor Create(const aOnIdle: TOnIdleSynBackgroundThread; const aThreadName: RawUtf8; const OnBeforeExecute: TOnNotifyThread = nil; const OnAfterExecute: TOnNotifyThread = nil); reintroduce;

*初始化執行緒

  • 如果aOnIdle未設定(即等於nil),它將簡單地等待後臺程序完成,直到RunAndWait()返回
  • 可以定義一些回撥來巢狀執行緒執行,例如分配給TRestServer.BeginCurrentThread/EndCurrentThread*

destructor Destroy; override;

終結執行緒


function RunAndWait(OpaqueParam: pointer): boolean;

*在後臺執行緒中非同步啟動Process抽象方法

  • 等待程序完成,同時呼叫OnIdle()回撥
  • 在後臺執行緒中引發的任何異常都將在呼叫者執行緒中轉換
  • 如果self未設定,或者從當前正在處理的同一執行緒中呼叫(以避免從OnIdle()回撥引發的競態條件),則返回false
  • 當後臺程序完成時返回true
  • OpaqueParam將用於指定後臺程序的執行緒安全內容
  • 此方法是執行緒安全的,即它將等待由另一個執行緒啟動的任何程序:可以從任何執行緒呼叫此方法,即使其主要目的是從主UI執行緒呼叫*

property OnAfterProcess: TOnNotifyThread read fOnAfterProcess write fOnAfterProcess;

在每個Process之後在Execute中觸發的可選回撥事件


property OnBeforeProcess: TOnNotifyThread read fOnBeforeProcess write fOnBeforeProcess;

在每個Process之前在Execute中觸發的可選回撥事件


property OnIdle: TOnIdleSynBackgroundThread read fOnIdle write fOnIdle;

*在遠端阻塞程序期間迴圈執行的回撥事件,例如,在請求時間較長時重新整理UI

  • 可以為此屬性分配一個回撥,例如呼叫Application.ProcessMessages,在後臺執行緒中執行遠端請求,但讓UI保持響應:mORMotUILogin.pas中的TLoginForm.OnIdleProcess和OnIdleProcessForm方法將滿足此屬性的預期
  • 如果OnIdle未設定(即等於nil),它將簡單地等待後臺程序完成,直到RunAndWait()返回*

property OnIdleBackgroundThreadActive: boolean read GetOnIdleBackgroundThreadActive;

*如果後臺執行緒處於活動狀態,並且在處理過程中呼叫了OnIdle事件,則為TRUE

  • 例如,用於確保使用者介面訊息不會重新進入*

1.3.10. TSynBackgroundThreadEvent

TSynBackgroundThreadEvent = class(TSynBackgroundThreadMethodAbstract)

允許後臺執行緒處理方法回撥


constructor Create(const aOnProcess: TOnProcessSynBackgroundThread; const aOnIdle: TOnIdleSynBackgroundThread; const aThreadName: RawUtf8); reintroduce;

*初始化執行緒

  • 如果aOnIdle未設定(即等於nil),它將簡單地等待後臺程序完成,直到RunAndWait()返回*

property OnProcess: TOnProcessSynBackgroundThread read fOnProcess write fOnProcess;

*提供一個在後臺執行緒中執行的方法處理程式

  • 由RunAndWait()方法觸發 - 該方法將等待直到完成
  • 在RunAndWait()中指定的OpaqueParam將在此處提供*

1.3.11. TSynBackgroundThreadMethod

TSynBackgroundThreadMethod = class(TSynBackgroundThreadMethodAbstract)

允許後臺執行緒處理可變的TThreadMethod回撥


procedure RunAndWait(Method: TThreadMethod); reintroduce;

*執行一次提供的TThreadMethod回撥

  • 使用此方法,而不是繼承的RunAndWait()*

1.3.12. TSynBackgroundThreadProcedure

TSynBackgroundThreadProcedure = class(TSynBackgroundThreadMethodAbstract)

允許後臺執行緒處理過程回撥


constructor Create(aOnProcess: TOnProcessSynBackgroundThreadProc; const aOnIdle: TOnIdleSynBackgroundThread; const aThreadName: RawUtf8); reintroduce;

*初始化執行緒

  • 如果aOnIdle未設定(即等於nil),它將簡單地等待後臺程序完成,直到RunAndWait()返回*

property OnProcess: TOnProcessSynBackgroundThreadProc read fOnProcess write fOnProcess;

*提供一個在後臺執行緒中執行的過程處理程式

  • 由RunAndWait()方法觸發 - 該方法將等待直到完成
  • 在RunAndWait()中指定的OpaqueParam將在此處提供*

1.3.13. TSynBackgroundThreadProcess

TSynBackgroundThreadProcess = class(TSynBackgroundThreadAbstract)

能夠在給定週期速率下執行方法的TThread


constructor Create(const aThreadName: RawUtf8; const aOnProcess: TOnSynBackgroundThreadProcess; aOnProcessMS: cardinal; const aOnBeforeExecute: TOnNotifyThread = nil; const aOnAfterExecute: TOnNotifyThread = nil; aStats: TSynMonitorClass = nil; CreateSuspended: boolean = false); reintroduce; virtual;

*初始化執行緒以進行週期性任務處理

  • 當呼叫ProcessEvent.SetEvent或自上次處理以來已經過去了aOnProcessMS毫秒週期時,將呼叫aOnProcess
  • 如果aOnProcessMS為0,將等待直到呼叫ProcessEvent.SetEvent
  • 可以定義一些回撥來巢狀執行緒執行,例如分配給TRestServer.BeginCurrentThread/EndCurrentThread*

destructor Destroy; override;

終結執行緒並等待其結束


property OnException: TNotifyEvent read fOnException write fOnException;

*當OnProcess引發異常時執行的事件回撥

  • 提供的Sender引數是引發的異常例項*

property OnProcess: TOnSynBackgroundThreadProcess read fOnProcess;

訪問週期性任務的實現事件


property OnProcessMS: cardinal read fOnProcessMS write fOnProcessMS;

訪問週期性任務處理的延遲(以毫秒為單位)


property Stats: TSynMonitor read fStats;

*處理統計資訊

  • 如果在類建構函式中aStats為nil,則可能為nil*

1.3.14. TSynBackgroundTimerTask

TSynBackgroundTimerTask = record

TSynBackgroundTimer內部註冊列表使用


1.3.15. TSynBackgroundTimer

TSynBackgroundTimer = class(TSynBackgroundThreadProcess)

*能夠在後臺執行緒中以週期速率執行一個或多個任務的TThread

  • 例如,透過繼承的TRestBackgroundTimer,由TRest.TimerEnable/TimerDisable方法使用
  • 每個程序可以有自己的text訊息FIFO佇列
  • 如果你expect更新某些GUI,你應該使用TTimer元件(例如,週期為200ms),因為TSynBackgroundTimer將使用自己的獨立執行緒*

constructor Create(const aThreadName: RawUtf8; const aOnBeforeExecute: TOnNotifyThread = nil; aOnAfterExecute: TOnNotifyThread = nil; aStats: TSynMonitorClass = nil; aLogClass: TSynLogClass = nil); reintroduce; virtual;

*初始化執行緒以進行週期性taskprocessing

  • 你可以定義一些回撥來巢狀執行緒執行,例如分配給TRestServer.BeginCurrentThread/EndCurrentThread,如TRestBackgroundTimer.Create所做的那樣*

destructor Destroy; override;

終結執行緒


function DeQueue(const aOnProcess: TOnSynBackgroundTimerProcess; const aMsg: RawUtf8): boolean;

*從processing列表中移除一條訊息

  • 提供的訊息將在與aOnProcess相關聯的內部FIFO列表中搜尋,如果找到則從列表中移除
  • aOnProcess應透過之前的呼叫到Enable()方法進行註冊
  • 如果成功則返回true,如果提供的訊息未註冊則返回false*

function Disable(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;

*取消定義一個在週期秒數上執行的task

  • aOnProcess應透過之前的呼叫到Enable()方法進行註冊
  • 如果成功則返回true,如果提供的task未註冊則返回false
  • 對於mORMot服務上的後臺程序,考慮使用TRestServer的TimerEnable/TimerDisable方法及其TSynBackgroundTimer執行緒*

function EnQueue(const aOnProcess: TOnSynBackgroundTimerProcess; const aMsgFmt: RawUtf8; const Args: array of const; aExecuteNow: boolean = false): boolean; overload;

*在task的下次執行期間新增一條格式化訊息進行處理

  • 提供的訊息將被新增到與aOnProcess相關聯的內部FIFO列表中,然後每次呼叫時作為aMsg引數提供
  • 如果aExecuteNow為true,則不會等待下一個aOnProcessSecs的發生
  • aOnProcess應透過之前的呼叫到Enable()方法進行註冊
  • 如果成功則返回true,如果提供的task未註冊則返回false*

function EnQueue(const aOnProcess: TOnSynBackgroundTimerProcess; const aMsg: RawUtf8; aExecuteNow: boolean = false): boolean; overload;

*在task的下次執行期間新增一條訊息進行處理

  • 提供的訊息將被新增到與aOnProcess相關聯的內部FIFO列表中,然後每次呼叫時作為aMsg引數提供
  • 如果aExecuteNow為true,則不會等待下一個aOnProcessSecs的發生
  • aOnProcess應透過之前的呼叫到Enable()方法進行註冊
  • 如果成功則返回true,如果提供的task未註冊則返回false*

function ExecuteNow(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;

*立即執行一個task,不等待下一個aOnProcessSecs的發生

  • aOnProcess應透過之前的呼叫到Enable()方法進行註冊
  • 如果成功則返回true,如果提供的task未註冊則返回false*

function ExecuteOnce(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;

*立即執行一個task,不等待下一個aOnProcessSecs的發生

  • aOnProcess不應透過之前的呼叫到Enable()方法進行註冊*

procedure Enable(const aOnProcess: TOnSynBackgroundTimerProcess; aOnProcessSecs: cardinal);

*定義一個在週期秒數上執行的task的處理方法

  • 對於mORMot服務上的後臺程序,考慮使用TRest的TimerEnable/TimerDisable方法及其關聯的BackgroundTimer執行緒*

procedure WaitUntilNotProcessing(timeoutsecs: integer = 10);

等待直到沒有後臺task正在處理


property Processing: boolean read fProcessing;

如果當前正在處理某些tasks,則返回TRUE


property Task: TSynBackgroundTimerTaskDynArray read fTask;

對內部task列表的低階訪問


property Tasks: TDynArrayLocked read fTasks;

對內部task列表的執行緒安全包裝的低階訪問 Low-level access to the internal task list wrapper and safe



1.3.16. TBlockingProcess

TBlockingProcess = class(TSynEvent)

*一個訊號量,用於等待某個程序完成

  • 例如,在mormot.rest.server.pas中的TBlockingCallback中使用
  • 一旦建立,程序將透過WaitFor呼叫進行阻塞,當程序後臺執行緒呼叫NotifyFinished時,阻塞將被釋放*

constructor Create(aTimeOutMs: integer); reintroduce; overload; virtual;

*初始化訊號量例項

  • 指定阻塞執行應被視為失敗的超時毫秒數週期(如果設定為0,則預設使用3000)
  • 建立一個與之關聯的互斥鎖,並由該例項擁有*

constructor Create(aTimeOutMs: integer; aSafe: PSynLocker); reintroduce; overload; virtual;

*重寫以reset相關引數並初始化訊號量例項

  • 指定阻塞執行應被視為失敗的超時毫秒數週期(如果設定為0,則預設使用3000)
  • 應提供一個關聯的互斥鎖*

destructor Destroy; override;

終結例項


function NotifyFinished(alreadyLocked: boolean = false): boolean; virtual;

*當後臺程序完成時應該被呼叫

  • 呼叫者隨後將允許其WaitFor方法返回
  • 如果成功則返回TRUE(即狀態不是evRaised或evTimeout)
  • 如果例項已經被鎖定(例如,從TBlockingProcessPool.FromCallLocked檢索時),你可以設定alreadyLocked=TRUE*

function Reset: boolean; virtual;

*只是一個包裝器,用於將內部Event狀態重置為evNone

  • 在成功完成WaitFor/NotifyFinished過程後,可以使用它來重用同一個TBlockingProcess例項
  • 如果成功則返回TRUE(即狀態不是evWaiting),將當前狀態設定為evNone,並將Call屬性設定為0
  • 如果當前正在進行WaitFor過程,則返回FALSE*

function WaitFor: TBlockingEvent; reintroduce; overload; virtual;

*呼叫以等待NotifyFinished()被呼叫或觸發超時

  • 返回程序的最終狀態,即evRaised或evTimeOut*

function WaitFor(TimeOutMS: integer): TBlockingEvent; reintroduce; overload;

*呼叫以等待NotifyFinished()被呼叫或觸發超時

  • 返回程序的最終狀態,即evRaised或evTimeOut*

procedure Lock;

只是fSafe^.Lock的一個包裝器


procedure Unlock;

只是fSafe^.Unlock的一個包裝器


property Event: TBlockingEvent read fEvent;

*程序的當前狀態

  • 使用Reset方法可以在WaitFor過程後重用此例項*

property TimeOutMs: integer read fTimeOutMS;

在建構函式級別定義的超時週期,以毫秒為單位


1.3.17. TBlockingProcessPoolItem

TBlockingProcessPoolItem = class(TBlockingProcess)

*在TBlockingProcessPool中使用的訊號量

  • 此類訊號量具有一個Call欄位來標識每次執行*

property Call: TBlockingProcessPoolCall read fCall;

*一個唯一識別符號,當被TBlockingProcessPool擁有時,用於標識每次執行

  • Reset方法會將此欄位恢復為其預設值0,以便重用或重新開始新的執行*

這樣,TBlockingProcessPoolItem類作為 TBlockingProcess的子類,在繼承其訊號量功能的基礎上,增加了 Call屬性來支援在 TBlockingProcessPool中的唯一標識,使得在池化管理訊號量時能夠區分不同的執行例項。透過 Reset方法,可以重置訊號量的狀態以及 Call屬性,以便迴圈利用。

1.3.18. TBlockingProcessPool

TBlockingProcessPool = class(TSynPersistent)

Manage a pool of TBlockingProcessPoolItem instances
- each call will be identified via a TBlockingProcessPoolCall unique value
- to be used to emulate e.g. blocking execution from an asynchronous event-driven DDD process
- it would also allow to re-use TEvent system resources


constructor Create(aClass: TBlockingProcessPoolItemClass = nil); reintroduce;

Set TBlockingProcessPoolItem.Call initialize the pool, for a given implementation class


destructor Destroy; override;

Finalize the pool
- would also force all pending WaitFor to trigger a evTimeOut


function FromCall(call: TBlockingProcessPoolCall; locked: boolean = false): TBlockingProcessPoolItem; virtual;

Retrieve a TBlockingProcess from its call identifier
- may be used e.g. from the callback of the asynchronous process to set some additional parameters to the inherited TBlockingProcess, then call NotifyFinished to release the caller WaitFor
- if leavelocked is TRUE, the returned instance would be locked: caller should execute result.Unlock or NotifyFinished(true) after use


function NewProcess(aTimeOutMs: integer): TBlockingProcessPoolItem; virtual;

Book a TBlockingProcess from the internal pool
- returns nil on error (e.g. the instance is destroying)
- or returns the blocking process instance corresponding to this call; its Call property would identify the call for the asynchronous callback, then after WaitFor, the Reset method should be run to release the mutex for the pool


1.3.19. TSynParallelProcessThread

TSynParallelProcessThread = class(TSynBackgroundThreadMethodAbstract)

Thread executing process for TSynParallelProcess


1.3.20. TSynParallelProcess

TSynParallelProcess = class(TSynPersistentLock)

Allow parallel execution of an index-based process in a thread pool
- will create its own thread pool, then execute any method by spliting the work into each thread


constructor Create(ThreadPoolCount: integer; const ThreadName: RawUtf8; const OnBeforeExecute: TOnNotifyThread = nil; const OnAfterExecute: TOnNotifyThread = nil; MaxThreadPoolCount: integer = 32); reintroduce; virtual;

Initialize the thread pool
- you could define some callbacks to nest the thread execution, e.g. assigned to TRestServer.BeginCurrentThread/EndCurrentThread
- up to MaxThreadPoolCount=32 threads could be setup (you may allow a bigger value, but interrest of this thread pool is to have its process saturating each CPU core)
- if ThreadPoolCount is 0, no thread would be created, and process would take place in the current thread


destructor Destroy; override;

Finalize the thread pool


procedure ParallelRunAndWait(const Method: TOnSynParallelProcess; MethodCount: integer; const OnMainThreadIdle: TNotifyEvent = nil);

Run a method in parallel, and wait for the execution to finish
- will split Method[0..MethodCount-1] execution over the threads
- in case of any exception during process, an ESynParallel exception would be raised by this method
- if OnMainThreadIdle is set, the current thread (which is expected to be e.g. the main UI thread) won't process anything, but call this event during waiting for the background threads


property ParallelRunCount: integer read fParallelRunCount;

How many threads have been activated


property ThreadName: RawUtf8 read fThreadName;

Some text identifier, used to distinguish each owned thread


property ThreadPoolCount: integer read fThreadPoolCount;

How many threads are currently in this instance thread pool


1.3.21. TSynThread

TSynThread = class(TThreadAbstract)

A simple TThread with a "Terminate" event run in the thread context
- the TThread.OnTerminate event is run within Synchronize() so did not match our expectations to be able to release the resources in the thread context which created them (e.g. for COM objects, or some DB drivers)
- used internally by THttpServerGeneric.NotifyThreadStart() - you should not have to use the protected fOnThreadTerminate event handler
- also define a Start method for compatibility with older versions of Delphi


constructor Create(CreateSuspended: boolean); reintroduce; virtual;

Initialize the thread instance, in non suspended state


function SleepOrTerminated(MS: cardinal): boolean;

Safe version of Sleep() which won't break the thread process
- returns TRUE if the thread was Terminated
- returns FALSE if successfully waited up to MS milliseconds


property StartNotified: TObject read fStartNotified write fStartNotified;

Ensure fOnThreadTerminate is called only if NotifyThreadStart has been done


1.3.22. TNotifiedThread

TNotifiedThread = class(TSynThread)

Abstract class to implement a thread with start/stop notifications
- e.g. a server thread
- do not use this class, but rather the THttpServer, THttpApiServer or TWebSocketServer (as defined in mormot.net.websock)


constructor Create(CreateSuspended: boolean; const OnStart, OnStop: TOnNotifyThread; const ProcessName: RawUtf8); reintroduce; virtual;

Initialize the server instance, in non suspended state


procedure SetServerThreadsAffinityPerCpu( const log: ISynLog; const threads: TThreadDynArray);

Assign each thread to a single logical CPU core
- for instance, for a HTTP server, it may ensure better scalability with short-living requests and high number of threads


procedure SetServerThreadsAffinityPerSocket( const log: ISynLog; const threads: TThreadDynArray);

Assign each thread to a single hardware CPU socket
- for instance, for a HTTP server, it may ensure better scalability on complex hardware with several physical CPU packages - but it is very picky, so should be enabled only with proper testing on the actual HW


1.3.23. TLoggedThread

TLoggedThread = class(TSynThread)

Abstract class to implement a thread with logging notifications


constructor Create(CreateSuspended: boolean; Logger: TSynLogClass; const ProcName: RawUtf8); reintroduce; virtual;

Initialize the server instance, in non suspended state


procedure TerminateAndWaitFinished(TimeOutMs: integer = 5000); virtual;

Notify the thread to be terminated, and wait for DoExecute to finish


property LogClass: TSynLogClass read fLogClass;

The associated logging class


property ProcessName: RawUtf8 read fProcessName;

The name of this thread, as supplied to SetCurrentThreadName()


1.3.24. TLoggedWorkThread

TLoggedWorkThread = class(TLoggedThread)

A class able to run some process in a background thread
- with proper logging and eventual ending notification


constructor Create(Logger: TSynLogClass; const ProcessName: RawUtf8; const NameValuePairs: array of const; const OnExecute: TOnLoggedWorkProcess; const OnExecuted: TNotifyEvent = nil); reintroduce; overload;

This constructor will directly start the thread in background
- with the context as a TDocVariantData object with name/value pairs


constructor Create(Logger: TSynLogClass; const ProcessName: RawUtf8; Sender: TObject; const OnExecute: TNotifyEvent; const OnExecuted: TNotifyEvent = nil); reintroduce; overload;

This constructor will directly start the thread in background
- with the context as a regular TNotifyEvent


1.3.25. TSynThreadPoolWorkThread

TSynThreadPoolWorkThread = class(TSynThread)

Defines the work threads used by TSynThreadPool


constructor Create(Owner: TSynThreadPool); reintroduce;

Exception-safe call of fOwner.Task() initialize the thread


destructor Destroy; override;

Finalize the thread


procedure Execute; override;

Will loop for any pending task, and execute fOwner.Task()


property Owner: TSynThreadPool read fOwner;

The associated thread pool


1.3.26. TSynThreadPool

TSynThreadPool = class(TObject)

A simple Thread Pool, used e.g. for fast handling HTTP/1.0 requests
- implemented over I/O Completion Ports under Windows, or a classical Event-driven approach under Linux/POSIX


constructor Create(NumberOfThreads: integer = 32; aOverlapHandle: THandle = INVALID_HANDLE_VALUE; const aName: RawUtf8 = '');

Initialize a thread pool with the supplied number of threads
- abstract Task() virtual method will be called by one of the threads
- up to 256 threads can be associated to a Thread Pool
- on Windows, can optionaly accept aOverlapHandle - a handle previously opened using Windows Overlapped I/O (IOCP)
- on POSIX, aQueuePendingContext=true will store the pending context into an internal queue, so that Push() returns true until the queue is full


destructor Destroy; override;

Shut down the Thread pool, releasing all associated threads


function Push(aContext: pointer; aWaitOnContention: boolean = false): boolean;

Let a task (specified as a pointer) be processed by the Thread Pool
- returns false if there is no idle thread available in the pool and Create(aQueuePendingContext=false) was used (caller should retry later); if aQueuePendingContext was true in Create, or IOCP is used, the supplied context will be added to an internal list and handled when possible
- if aWaitOnContention is default false, returns immediately when the queue is full; set aWaitOnContention=true to wait up to ContentionAbortDelay ms and retry to queue the task


property ContentionAbortCount: cardinal read fContentionAbortCount;

How many tasks were rejected due to thread pool contention
- if this number is high, consider setting a higher number of threads, or profile and tune the Task method


property ContentionAbortDelay: integer read fContentionAbortDelay write fContentionAbortDelay;

Milliseconds delay to reject a connection due to contention
- default is 5000, i.e. 5 seconds wait for some room to be available in the IOCP or aQueuePendingContext internal list
- during this delay, no new connection is available (i.e. Accept is not called), so that a load balancer could detect the contention and switch to another instance in the pool, or a direct client may eventually have its connection rejected, so won't start sending data


property ContentionCount: cardinal read fContentionCount;

How many times the pool waited for an available slot in the queue
- contention won't fail immediately, but will retry until ContentionAbortDelay
- any high number here may better increase the threads count
- use this property and ContentionTime to compute the average contention time


property ContentionTime: Int64 read fContentionTime;

Total milliseconds spent waiting for an available slot in the queue
- contention won't fail immediately, but will retry until ContentionAbortDelay
- any high number here requires code refactoring of the Task method


property RunningThreads: integer read fRunningThreads;

How many threads are currently processing tasks in this thread pool
- is in the range 0..WorkThreadCount


property WorkThread: TSynThreadPoolWorkThreads read fWorkThread;

Low-level access to the threads defined in this thread pool


property WorkThreadCount: integer read fWorkThreadCount;

How many threads are available in the pool
- maps Create() parameter, i.e. 32 by default


1.4. Types implemented in the mormot.core.threads unit

1.4.1. TBlockingEvent

TBlockingEvent = ( evNone, evWaiting, evTimeOut, evRaised );

The current state of a TBlockingProcess instance


1.4.2. TBlockingProcessPoolCall

TBlockingProcessPoolCall = type integer;

Used to identify each TBlockingProcessPool call
- allow to match a given TBlockingProcessPoolItem semaphore


1.4.3. TBlockingProcessPoolItemClass

TBlockingProcessPoolItemClass = class of TBlockingProcessPoolItem;

Class-reference type (metaclass) of a TBlockingProcess


1.4.4. TEvent

TEvent = syncobjs.TEvent;

Defined here to avoid explicit link to syncobjs in uses clause
- note that you may better use TSynEvent from mormot.core.os.pas


1.4.5. TOnIdleSynBackgroundThread

TOnIdleSynBackgroundThread = procedure(Sender: TSynBackgroundThreadAbstract; ElapsedMS: integer) of object;

Idle method called by TSynBackgroundThreadAbstract in the caller thread during remote blocking process in a background thread
- typical use is to run Application.ProcessMessages, e.g. for TRestClientUri.Uri() to provide a responsive UI even in case of slow blocking remote access
- provide the time elapsed (in milliseconds) from the request start (can be used e.g. to popup a temporary message to wait)
- is call once with ElapsedMS=0 at request start
- is call once with ElapsedMS=-1 at request ending
- see TLoginForm.OnIdleProcess and OnIdleProcessForm in mORMotUILogin.pas


1.4.6. TOnLoggedWorkProcess

TOnLoggedWorkProcess = procedure(const Context: TDocVariantData) of object;

Event called in a background thread by TLoggedWorkThread.Create


1.4.7. TOnNotifyThread

TOnNotifyThread = procedure(Sender: TThread) of object;

Event prototype used e.g. by TSynBackgroundThreadAbstract and TSynThread callbacks


1.4.8. TOnProcessSynBackgroundThread

TOnProcessSynBackgroundThread = procedure(Sender: TSynBackgroundThreadEvent; ProcessOpaqueParam: pointer) of object;

Background process method called by TSynBackgroundThreadEvent
- will supply the OpaqueParam parameter as provided to RunAndWait() method when the Process virtual method will be executed


1.4.9. TOnProcessSynBackgroundThreadProc

TOnProcessSynBackgroundThreadProc = procedure(ProcessOpaqueParam: pointer);

Background process procedure called by TSynBackgroundThreadProcedure
- will supply the OpaqueParam parameter as provided to RunAndWait() method when the Process virtual method will be executed


1.4.10. TOnSynBackgroundThreadProcess

TOnSynBackgroundThreadProcess = procedure(Sender: TSynBackgroundThreadProcess) of object;

Event callback executed periodically by TSynBackgroundThreadProcess


1.4.11. TOnSynBackgroundTimerProcess

TOnSynBackgroundTimerProcess = procedure(Sender: TSynBackgroundTimer; const Msg: RawUtf8) of object;

Event callback executed periodically by TSynBackgroundThreadProcess
- Msg is '' if there is no pending message in this task FIFO
- Msg is set for each pending message in this task FIFO
- on mORMot 1, there was a TWaitEvent parameter which is now removed


1.4.12. TOnSynParallelProcess

TOnSynParallelProcess = procedure(IndexStart, IndexStop: integer) of object;

Callback implementing some parallelized process for TSynParallelProcess
- if 0<=IndexStart<=IndexStop, it should execute some process


1.4.13. TPendingTaskListItemDynArray

TPendingTaskListItemDynArray = array of TPendingTaskListItem;

Internal list definition, used by TPendingTaskList storage


1.4.14. TSynBackgroundThreadProcessStep

TSynBackgroundThreadProcessStep = ( flagIdle, flagStarted, flagFinished, flagDestroying );

State machine status of the TSynBackgroundThreadAbstract process


1.4.15. TSynBackgroundThreadProcessSteps

TSynBackgroundThreadProcessSteps = set of TSynBackgroundThreadProcessStep;

State machine statuses of the TSynBackgroundThreadAbstract process


1.4.16. TSynBackgroundTimerTaskDynArray

TSynBackgroundTimerTaskDynArray = array of TSynBackgroundTimerTask;

Protect Msg[] list stores TSynBackgroundTimer internal registration list


1.4.17. TThreadDynArray

TThreadDynArray = array of TThread;

A dynamic array of TThread


1.4.18. TWaitResult

TWaitResult = syncobjs.TWaitResult;

Defined here to avoid explicit link to syncobjs in uses clause
- note that you may better use TSynEvent from mormot.core.os.pas


1.5. Constants implemented in the mormot.core.threads unit

1.5.1. THREADPOOL_MAXTHREADS

THREADPOOL_MAXTHREADS = 256;

Allow up to 256 * 2MB = 512MB of RAM for the TSynThreadPoolWorkThread stack


1.5.2. wrSignaled

wrSignaled = syncobjs.wrSignaled;

Please favor TSynEvent from mormot.core.os instead of TEvent defined here to avoid explicit link to syncobjs in uses clause

相關文章