Delphi - 调整线程休眠时间

时间:2009-06-06 21:20:06

标签: database multithreading delphi sleep

我的应用程序中有几个线程在后台运行。它们连接到数据库并执行一些耗时的选择查询。在大多数情况下,这些查询只返回几条记录。然而,有时他们可能会返回数万条记录。然后将所有这些循环处理。

因为这种情况可能同时发生在多个线程中,所以我不希望我的应用程序在这些线程处理数据时使用100%的CPU时间;我也不想让所有线程争夺处理器的时间。因此,我在这些线程中的循环的每次迭代中调用Sleep()函数。

但是,我不知道如何调整睡眠时间。我不希望循环永远持续,所以睡眠时间不能太长。我在每次迭代中将它设置为2毫秒(在每个线程中)(为什么2ms? - 这是一个很好的问题:))。

另一方面,我认为我可以延长睡眠时间,但每n次迭代只调用一次睡眠(比方说,每50次迭代睡眠(100次))。我应该选择哪种方法?循环的一次迭代每次约30毫秒(没有任何睡眠)。

请告知。

谢谢!
马里乌什。

4 个答案:

答案 0 :(得分:9)

调用 Sleep()是没有意义的。使用您可以获得的所有处理能力,让系统了解如何最好地安排线程。调用 Sleep()只会导致额外的上下文切换并降低吞吐量。如果后台处理干扰了您的主线程或其他应用程序,则相应地降低后台线程的优先级。

如果您想让线程休眠以限制它们为消费者生成的数据量,请查看生产者 - 消费者队列。让生产者线程在他们的队列已满时简单地阻塞,这样你根本不需要摆弄时间。

另请注意,使用最大CPU通常是一件好事,尤其是在现代处理器上。即使在具有短时间高负载的笔记本电脑上也比人为地延长任务所需的时间更好,因为处理器/整个系统将能够更快地进入低功率状态。

答案 1 :(得分:3)

您最好只制作低优先级线程,让它们在没有睡眠的情况下工作,否则您不会使用CPU的全部功能。例如,在多核/多CPU系统上。或者,如果您的系统100%闲置:为什么要等待或睡觉?

但是如果你需要一些睡眠,请注意睡眠(1)因为默认的Windows时间片而等待10-15ms(!)。您可以使用MMSystem.pas单元的timeBeginPeriod(1)将分辨率设置为1ms :-)(我将其用于串行通信)。

答案 2 :(得分:2)

使用sleep来控制线程可能有更好的方法。由于您的数据库调用可以返回1-1000个记录进行处理,因此将应用程序分成两层可能是有意义的,可能使用消息队列来缓冲请求。您的应用程序可以调用数据服务,然后数据服务将运行查询并将单个数据消息(或消息块等)分派到队列。然后,您的应用可以根据需要创建尽可能多的线程来处理消息。更多线程意味着以CPU为代价加快处理速度,但您可以对其进行调整以获得正确的平衡。

答案 3 :(得分:0)

使用来自System.Classes的TThread.Sleep(),而不是来自WinApi.Windows的Sleep()

// Winapi.Windows contains GetTickCount and Sleep
// System.Classes contains TThread (universal option) // TThread.GetTickCount() // TThread.Sleep()
uses System.Types, System.Classes, Vcl.Forms;

//然后在您的流程中使用以下

TThread.Sleep(0);

Application.ProcessMessages(); // clear all Vcl messages  // part of Vcl.Forms
CheckSynchronize(); // check all threaded events