TWorkStealingQueue的目的是什么以及如何使用它?

时间:2018-07-28 13:13:41

标签: multithreading delphi threadpool

我正在开发一个程序,用于从潜在的大目录结构及其许多文件结构(约100万个)中迁移文件。
我的迁移代码已经运行良好,并且我正在使用一个类来迭代目录结构,识别文件以依次依次迁移它们。

现在,我想更好地利用目标计算机的可用CPU资源,并进行那些迁移,以异步方式从System.Threading.TThreadPool抓取线程来执行这些线程。

我对ITask界面以及如何利用TTask来设置一系列任务(它们将与一个TThreadPool实例一起进行管理)非常了解。 br /> 尽管设置了一个大的TArray<ITask>数组,并在所有目录都经过时等待完成,但这似乎是一种不合适且效率低下的方法(尤其是在内存消耗方面)。

我认为我需要的只是一个简单的线程安全的 producer / consumer 队列,该队列随着工作线程可用于消耗任务的任务而增长和收缩,并完成它们。

现在,我在Emba文档中发现了一种听起来令人鼓舞的东西,称为TWorkStealingQueue,但通常情况下,该文档非常贫乏,并且缺乏简洁的示例来说明如何使用它。

它会归结为类似的东西

TMigrationFileWalker = class(TFileWalker) 
strict private
    var
       FPendingMigrationTasks : TArray<ITask>;

    function createMigrationTask(const filename : string) : ITask;
strict protected
    procedure onHandleFile(const filename : string); override;
public
    procedure walkDirectoryTree(const startDir : string); override;
end;

implementation

procedure TMigrationFileWalker.onHandleFile(const filename : string);
var
    migrationTask : ITask;
begin
    migrationTask := createMigrationTask(filename);
    self.FPendingMigrationTasks := self.FPendingMigrationTasks + [migrationTask];
    migrationTask.Start();
end;

procedure walkDirectoryTree(const startDir : string);
begin
    inherited walkDirectoryTree(startDir);
    TTask.WaitForAll(self.FPendingMigrationTasks,SOME_REASONABLE_TIMEOUT);
end;

当然,我可以拥有一个线程安全的PC队列,并管理处理该线程的线程。但是,可以保证它可以与线程池一起使用,我想利用它附带的已经可用的负载平衡机制。

周围的人是否已经使用TWorkStealingQueue,并且可以举一个简短的示例来说明如何在上述情况下使用它?或者至少要弄清楚该类的实际目的是什么,以防万一我从命名中完全误解了该类?

关于TWorkStealingQueue的一项研究并没有比重定向到不足的Embarcadero文档更好的结果。

0 个答案:

没有答案