8

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

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

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

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

请指教。

谢谢!
马吕斯。

4

4 回答 4

10

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

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

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

于 2009-06-06T21:39:54.757 回答
4

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

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

于 2009-06-08T09:49:51.803 回答
2

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

于 2009-06-06T21:30:13.403 回答
1

使用 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
于 2016-06-17T19:14:34.357 回答