在必须轮询的工作线程的主循环中,知道是否有工作要做,我让它睡觉以便不忙 - 等待。我如何确定睡眠的好长度? E. g。如果我每毫秒醒来,它根本就没用。如果我每十分钟醒来一次,可能会使应用看起来没有响应(取决于线程在做什么)。
我之前听说过cadrian在下面说过,人类用户不会注意到100毫秒左右的时间跨度,但是从机器方面接近它呢?在开始变得浪费之前,间隔有多小?
我想,它归结为this question更通用(即平台无关)的版本。
编辑:当然,问题应该首先被重新描述为“如何将其更改为事件模式而不是轮询”,但我们现在假设我不能或不想。
答案 0 :(得分:7)
有时轮询 答案。
但是,轮询的频率取决于线程正在做什么,所以要使其可配置。
我们有检查电子邮件的主题。他们可以检查外部邮箱,我们每30秒左右只检查邮箱(但它是可配置的)。每次检查都是通过网络进行的,每隔一秒钟或十分之一秒就会打电话给网络,30秒就可以了,如果电子邮件没有被处理则无关紧要。一些客户网站每5分钟检查一次。)
我们有其他线程轮询文件夹中的文件,和/或添加到数据库中的表的新请求。这些每1至5秒轮询一次(取决于他们正在做什么)。
现在无论您在轮询之间等待多长时间,我们都不会让任何线程睡眠时间超过一秒钟。原因是,如果您尝试停止线程休眠60秒的Windows服务,您可能需要在服务停止前等待60秒。
如果你需要匆忙降下机器,Rip Van Winkle线程将真正扭转你的mellon。
因此,请根据需要将您的轮询间隔分开,但不要长时间睡眠。
希望这有帮助
答案 1 :(得分:2)
您是否了解手术可以使用多长时间?也许一个范围?我假设你的线程基本上是这样做的:
while(!workComplete) {
Thread.Sleep(n);
}
如果它是一个UI工作线程,只要它们有某种进度指示器,任何高达半秒的地方都应该足够好。 UI应该在操作期间响应,因为它是后台线程,并且您肯定有足够的CPU时间可用于每500毫秒检查一次。当然,这取决于您的UI需要多少响应。但请记住,关于用户界面,这完全取决于感知性能。
另一种方法是exponential backoff。假设您在200 ms后检查输入是否已完成。如果还没有,下次睡眠400毫秒。如果在此之后它还没有完成,请睡眠800毫秒。等等。你应该确保在某个时候抛出TimeoutException以避免一些懒散的睡眠。
答案 2 :(得分:1)
如果同一应用程序的另一个线程提供了您的线程,那么您应该考虑使用事件模式而不是轮询。例如,在Java中,您将使用wait / notify。
否则,如果应用程序是面向用户的,那么每100ms左右进行一次民意调查就足够了。用户不会注意到。
答案 3 :(得分:0)
你应该发出一个信号来提醒线程。如果你正在使用c,你可以使用类似p-threads的条件变量。如果你正在使用更新的东西,比如.NET,你可以使用EventWaitHandle。我确信java和其他4gl有类似EventWaitHandle的类。
答案 4 :(得分:-1)
让它永远沉睡,当有可用的输入时将其唤醒?