mormot.core.threads--TSynParallelProcess
{ ************ 執行緒池中的並行執行 }
type
/// TSynParallelProcess 的並行化過程回撥
// - 如果 0<=IndexStart<=IndexStop,則應執行某些過程
TOnSynParallelProcess = procedure(IndexStart, IndexStop: integer) of object;
/// 為 TSynParallelProcess 執行過程的執行緒
TSynParallelProcessThread = class(TSynBackgroundThreadMethodAbstract)
protected
fMethod: TOnSynParallelProcess; // 回撥方法
fIndexStart, fIndexStop: integer; // 要處理的索引範圍
procedure Start(const Method: TOnSynParallelProcess; // 開始執行過程
IndexStart, IndexStop: integer);
/// 執行 fMethod(fIndexStart,fIndexStop)
procedure Process; override;
public
end;
/// 允許線上程池中並行執行基於索引的過程
// - 將建立自己的執行緒池,然後將工作分配給每個執行緒執行
TSynParallelProcess = class(TSynPersistentLock)
protected
fThreadName: RawUtf8; // 執行緒名稱
fPool: array of TSynParallelProcessThread; // 執行緒池
fThreadPoolCount: integer; // 執行緒池中的執行緒數
fParallelRunCount: integer; // 並行執行次數
public
/// 初始化執行緒池
// - 您可以定義一些回撥來巢狀執行緒執行,例如,分配給 TRestServer.BeginCurrentThread/EndCurrentThread
// - 最多可設定 MaxThreadPoolCount=32 個執行緒(您可以允許更大的值,但此執行緒池的目的是使其程序飽和每個 CPU 核心)
// - 如果 ThreadPoolCount 為 0,則不會建立執行緒,並且過程將在當前執行緒中執行
constructor Create(ThreadPoolCount: integer; const ThreadName: RawUtf8;
const OnBeforeExecute: TOnNotifyThread = nil; // 執行前通知回撥
const OnAfterExecute: TOnNotifyThread = nil; // 執行後通知回撥
MaxThreadPoolCount: integer = 32); reintroduce; virtual;
/// 終結執行緒池
destructor Destroy; override;
/// 並行執行一個方法,並等待執行完成
// - 將 Method[0..MethodCount-1] 的執行分散到執行緒中
// - 如果在過程中發生任何異常,則此方法將引發 ESynParallel 異常
// - 如果設定了 OnMainThreadIdle,則當前執行緒(例如,預期為主 UI 執行緒)將不會處理任何內容,但在等待後臺執行緒時呼叫此事件
procedure ParallelRunAndWait(const Method: TOnSynParallelProcess;
MethodCount: integer; const OnMainThreadIdle: TNotifyEvent = nil);
published
/// 已啟用的執行緒數
property ParallelRunCount: integer
read fParallelRunCount;
/// 此例項執行緒池中當前有多少執行緒
property ThreadPoolCount: integer
read fThreadPoolCount;
/// 一些文字識別符號,用於區分每個擁有的執行緒
property ThreadName: RawUtf8
read fThreadName;
end;
後期再整理!
由於 TSynParallelProcess
在mORMot 2框架中是一個假定的類(因為標準的mORMot 2庫並不直接包含這個類名,但它可能是一個自定義擴充套件或類似功能的類的代表),我將基於您提供的類定義來編寫一個假設的例程程式碼,這個程式碼將模擬在Free Pascal中使用這樣一個類。
請注意,以下程式碼將不會直接編譯,因為 TSynParallelProcess
和 TSynParallelProcessThread
的具體實現細節(如建構函式、解構函式和方法的內部邏輯)並未給出。但是,我將提供一個結構化的示例,展示如何使用這樣的類(如果它存在的話)。
program TSynParallelProcessDemo;
{$MODE DELPHI}
uses
SysUtils, Classes; // 引入必要的單元
// 假設TSynParallelProcess和TSynParallelProcessThread已經在某個單元中定義
// 這裡我們使用一個佔位符單元名YourMormotUnit
// 注意:在實際應用中,您需要替換'YourMormotUnit'為包含這些類的實際單元名
uses YourMormotUnit;
procedure MyParallelTask(IndexStart, IndexStop: integer);
begin
// 這裡是您的並行任務邏輯
WriteLn('Executing task with indices from ', IndexStart, ' to ', IndexStop);
// 模擬耗時操作
Sleep(100); // 假設每個任務需要一些時間來完成
end;
var
ParallelProcessor: TSynParallelProcess;
TaskCount: Integer;
begin
try
// 初始化任務計數(這裡假設我們有100個任務要並行處理)
// 注意:在實際應用中,您可能需要根據具體情況來確定這個值
TaskCount := 100;
// 建立TSynParallelProcess例項
// 注意:這裡我們假設ThreadPoolCount是一個合理的值,例如CPU核心數的兩倍
// 並且MaxThreadPoolCount足夠大以容納所需的執行緒數
// ThreadName是可選的,用於標識執行緒池中的執行緒
ParallelProcessor := TSynParallelProcess.Create(
System.SysUtils.GetProcessorCount * 2, // 假設執行緒池大小為CPU核心數的兩倍
'MyParallelTasks', // 執行緒名稱字首(可選)
nil, // OnBeforeExecute回撥(這裡不使用)
nil // OnAfterExecute回撥(這裡不使用)
);
try
// 並行執行任務並等待完成
// 注意:這裡的ParallelRunAndWait是假設的方法,它可能不直接存在於TSynParallelProcess中
// 您需要根據實際的方法簽名和邏輯來調整以下呼叫
// 由於我們沒有ParallelRunAndWait的具體實現,這裡只是一個示意性的呼叫
// 在實際中,您可能需要呼叫一個不同的方法,或者ParallelRunAndWait本身就需要您來實現
// 假設ParallelRunAndWait接受一個任務過程和任務總數作為引數
ParallelProcessor.ParallelRunAndWait(
@MyParallelTask, // 指向您的並行任務過程的指標
TaskCount // 要並行處理的任務總數
);
finally
// 銷燬TSynParallelProcess例項
ParallelProcessor.Free;
end;
except
on E: Exception do
WriteLn('An error occurred: ', E.Message);
end;
// 保持控制檯視窗開啟,直到使用者按任意鍵
WriteLn('Press Enter to exit...');
ReadLn;
end.
重要說明:
- 類和方法的存在性:上述程式碼假設
TSynParallelProcess
類及其ParallelRunAndWait
方法存在。在mORMot 2的標準庫中,這樣的類和方法可能不存在,或者它們的名稱和引數可能有所不同。 - 實現細節:由於我們沒有
TSynParallelProcess
和TSynParallelProcessThread
的具體實現,因此上述程式碼中的ParallelRunAndWait
呼叫是示意性的。在實際應用中,您需要根據實際可用的方法來實現並行任務的執行。 - 執行緒池大小:在建立
TSynParallelProcess
例項時,我使用了System.SysUtils.GetProcessorCount * 2
作為執行緒池的大小。這只是一個常見的啟發式方法,用於確定合理的執行緒數。然而,最佳執行緒數取決於您的具體應用程式和工作負載。 - 錯誤處理:程式碼中包含了基本的錯誤處理邏輯,用於捕獲並列印異常訊息。在實際應用中,您可能需要根據需要擴充套件這種錯誤處理。
- 單元引用:請將
uses YourMormotUnit;
中的YourMormotUnit
替換為包含TSynParallelProcess
和TSynParallelProcessThread
定義的實際單元名。如果這些類是您自定義的,那麼您需要確保它們已經被正確編譯幷包含在您的專案中。