【发布时间】:2021-05-06 18:35:48
【问题描述】:
我知道TTask并成功使用TTask.WaitForAll(array),以及TParallel.&For()。
但是现在想做一个看似简单的事情却不知道怎么做:
我有未知数量的物品进来,这可能是数百万或只有几件,而且我不提前知道。如何在没有队列的情况下并行处理它们(大约 4 个线程左右)?如果最大线程已经很忙,我想等待下一个空闲槽。像 TTask.Run() 这样的东西,直到它真正开始运行才会回来。
我想我只是在监督一些简单的事情......?
当我完成后,我想等待所有剩余的任务完成。但我当然不想将数百万个数组放在WaitForAll() 的数组中。
我可以想象一个可能的解决方案(但我不喜欢它,希望使用TTask 或类似的方法更简单):
- 将工作推送到
TThreadedQueue,如果队列已满,它会自动让我等待 - 启动 4 个线程并让它们循环从该队列中弹出
我知道在某些情况下这可能是首选方式,但我的情况不会从中受益(例如重用任何对象、连接等)。
伪代码会变得又好又干净:
MyThreadPool:= TMyThreadPool.Create(4);
while GetNextItem(out Item) do
//the following comes back when it has really been started:
MyThreadPool.Run(procedure begin Work(Item); end);
MyThreadPool.WaitFor;
【问题讨论】:
-
你只有两个选择。为每条记录创建一个
TTask并让TThreadPool为您处理限制,或者您将记录排队并自己限制它们。线程安全队列可以正常工作,并且仍然允许您重用对象。这只是你如何为它们编写逻辑的问题。我会使用记录对象池、连接对象轮询等。拉出记录,填充它,将其放入队列中。当一个线程从队列中拉出记录时,拉出一个连接并使用它,然后将记录和连接推回它们的池中。重复直到队列为空 -
嗨@RemyLebeau,因为它与数据库记录无关(在这种情况下我正在处理文件),所以我没有什么可以重用的。所以我希望有一些简单而简短的代码,比如
TParallel.@For。还有什么想法吗?我可以得到内部 TTask 队列的大小吗?
标签: multithreading delphi parallel-processing threadpool delphi-10.3-rio